2021年的第一篇文章;
JWT(JSON Web Token)是一个非常轻巧的规范;
这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
一个JWT实际上就是一个字符串;
我们可以通过这个字符串;
转化为用户信息;
写这篇文章的原因:
网上存在很多JWT的文章;
但是一般都是讲JWT算法与加密方式之类的;
云里雾里的;
集成JWT到Laravel项目里面;
我们使用Composer安装jwt扩展包:
composer require tymon/jwt-auth
注:如果你是用的 tymon/jwt-auth 是 0.5.* 版本的,请使用php artisan jwt:generate命令生成密钥。
注册需要用到的对应门面:
放在app.php 文件里面;
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class
下一步发布对应的配置文件;
php artisan vendor:publish --provider='Tymon\JWTAuth\Providers\JWTAuthServiceProvider'
最后生成密钥;
php artisan jwt:secret
接下来在用户的对应模型里面添加下面代码;
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* @var string 表名
*/
public $table = 'member';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
添加完成之后;
开始创建token;
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
use App\User;
use Tymon\JWTAuth\Facades\JWTAuth;
Route::get('/', function (){
// 创建token
$user = User::find(7);
$token = JWTAuth::fromUser($user);
dd($token);
// return view('welcome');
});
看看请求的的结果;
然后这个就是根据用户生成的token;
再把这个生成的token放在请求里面;
注意这里规定就是这种格式;
等下我们会说到为什么是这种格式;
Authorization : Bearer {your token}
我们在根据请求头里面的token转化成用户信息;
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
use App\User;
use Tymon\JWTAuth\Facades\JWTAuth;
Route::get('/', function (){
// 获取用户信息
$user = JWTAuth::parseToken()->authenticate();
dd($user);
// return view('welcome');
});
哈哈哈;
token成功转化为用户信息;
以上是生成token , 然后将token转化为用户信息;
下面是通过登录实现用户认证;
如果登录成功则返回相应用户的token;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthenticateController extends Controller
{
public function authenticate(Request $request)
{
// 获取登录用到的邮箱与密码参数
$credentials = $request->only('email', 'password');
try {
// 校验邮箱与密码是否成功
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// 创建token失败
return response()->json(['error' => 'could_not_create_token'], 500);
}
// 返回token信息
return response()->json(compact('token'));
}
}
tymon/jwt-auth 扩展还提供了两个中间件;
GetUserFromToken和RefreshToken;
前者用于在请求头和参数中检查是否包含token,并尝试对其解码;
后者会再次从请求中解析token;
并顺序刷新token(同时废弃老的token)并将其作为下一个响应的一部分;
要使用这两个中间件;
需要到app/Http/Kernel.php下的$routeMiddleware属性中注册它们:
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
//
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
];
最后我们来讲一下我们的请求头里面为什么是如下格式的:
Authorization : Bearer {your token}
我们来看一下源代码;
进入到 vendor\tymon\jwt-auth\src\Http\Parser\AuthHeaders.php
这个文件里面;
namespace Tymon\JWTAuth\Http\Parser;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;
class AuthHeaders implements ParserContract
{
/**
* The header name.
*
* @var string
*/
protected $header = 'authorization';
/**
* The header prefix.
*
* @var string
*/
protected $prefix = 'bearer';
/**
* Attempt to parse the token from some other possible headers.
*
* @param \Illuminate\Http\Request $request
*
* @return null|string
*/
protected function fromAltHeaders(Request $request)
{
return $request->server->get('HTTP_AUTHORIZATION') ?: $request->server->get('REDIRECT_HTTP_AUTHORIZATION');
}
/**
* Try to parse the token from the request header.
*
* @param \Illuminate\Http\Request $request
*
* @return null|string
*/
public function parse(Request $request)
{
$header = $request->headers->get($this->header) ?: $this->fromAltHeaders($request);
if ($header && preg_match('/'.$this->prefix.'\s*(\S+)\b/i', $header, $matches)) {
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sYXJhdmVsNS41LmNvbSIsImlhdCI6MTYxNDY3ODYwOSwiZXhwIjoxNjE0NjgyMjA5LCJuYmYiOjE2MTQ2Nzg2MDksImp0aSI6InBqNkxMOEowVTR3V0JJSXUiLCJzdWIiOjcsInBydiI6Ijg3ZTBhZjFlZjlmZDE1ODEyZmRlYzk3MTUzYTE0ZTBiMDQ3NTQ2YWEifQ.iTEbTl9eRCv9U500QcoGcGFlMqUjhqEhnwIO4NcZQWE
return $matches[1];
}
}
哈哈哈;
饭后小甜点;
学无止境;
本文为史大坨原创文章,转载无需和我联系,但请注明来自史大坨博客https://www.shidatuos.cn