laravel 之jwt认证使用详解
2018-04-20 本文已影响65人
空气KQ
作者
使用环境说明
centos7,php7,laravel5.2
jwt来源
https://packagist.org/packages/tymon/jwt-auth#1.0.0-rc.2
jwt介绍
JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
jwt原理
载荷(Payload)
{
"sub": "1",
"iss": "http://localhost:8000/auth/login",
"iat": 1451888119,
"exp": 1454516119,
"nbf": 1451888119,
"jti": "37c107e4609ddbcc9c096ea5ee76c667"
}
/*
sub: 该JWT所面向的用户
iss: 该JWT的签发者
iat(issued at): 在什么时候签发的token
exp(expires): token什么时候过期
nbf(not before):token在此时间之前不能被接收处理
jti:JWT ID为web token提供唯一标识
*/
将上面对象用 “base64编码”就形成了“载荷(Payload)”
头部(Header)
{
"typ": "JWT",
"alg": "HS256"
}
//HS256算法
进行Base64编码 就成了 头部(Header)
签名(签名)
两个编码后的字符串都用句号"."连接在一起
exp
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ
在使用HS256加密,这里需要引入一个安全密钥(secret),下面这个函数,不是PHP,自己去找下hs256如何加密,参考函数
crypt()
hash('sha256','string');
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
得到exp
wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4
最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT
JWT exp:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ.wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4
安装jwt
composer require tymon/jwt-auth:1.0.0-rc.2
这里指定了版本,我就先用1.0.0的
官方文档地址
http://jwt-auth.readthedocs.io/en/develop/
配置信息
配置的要求基本都是app引入服务商,配置config文件
config/app.php
'providers' => [
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
生成配置文件到config下
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
生成一个安全密钥
secret key
php artisan jwt:secret
实战部分
1、创建用户表,这里使用默认的
php artisan migrate
2、创建一个jwt的用户类
php artisan make:model Model/JwtUser
类的内容可以参考官方给的app/User.php文件
<?php
namespace App\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;//比User.php多了这个引入,下面并且继承这个接口
class JwtUser extends Authenticatable implements JWTSubject
{
protected $table="users";
// Rest omitted for brevity
protected $fillable = ['name', 'email'];
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 [];
}
}
3、配置auth.php文件的guard类型
在guards下面增加一个数组
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'apijwt'=>[
'driver'=>'jwt',
'provider'=>'jwt'
]
],
'providers' 下增加一个驱动
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'jwt' => [
'driver' => 'eloquent',
'model' => App\Model\JwtUser::class,//对应第二步创建的
]
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
4、创建一个控制器来认证一下jwt的使用
php artisan make:controller JwtController
写个注册操作,这里用了手动认证
/*注册*/
public function register(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
$credentials = [
'email' => $request->input('email'),
'password' => bcrypt($request->input('password')),
];
$user = JwtUser::create($credentials);
if($user)
{
$token = JWTAuth::fromUser($user);
return response()->json(['result' => $token]);
}
}
登录操作
/*登录*/
public function login(Request $request)
{
$credentials = $request->only('email','password');
if ( $token = Auth::guard($this->guard)->attempt($credentials) ) {
return response()->json(['result' => $token]);
} else {
return response()->json(['result'=>false]);
}
}
整个控制器如下
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Model\JwtUser;
use App\Http\Requests;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\Validator;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Auth;
class JwtController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
//
protected $guard = 'apijwt';
/*注册*/
public function register(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
$credentials = [
'email' => $request->input('email'),
'password' => bcrypt($request->input('password')),
];
$user = JwtUser::create($credentials);
if($user)
{
$token = JWTAuth::fromUser($user);
return response()->json(['result' => $token]);
}
}
public function index(){
echo 'Your has login ';
$token = JWTAuth::getToken();
$user = JWTAuth::parseToken()->authenticate();
echo "\n".var_dump($user);
}
/*登录*/
public function login(Request $request)
{
$credentials = $request->only('email','password');
if ( $token = Auth::guard($this->guard)->attempt($credentials) ) {
return response()->json(['result' => $token]);
} else {
return response()->json(['result'=>false]);
}
}
}
5、配置路由
Route::group(['prefix' => 'jwt'], function () {
Route::post('register', 'JwtController@register');
Route::post('login', 'JwtController@login');
Route::get('/', ['uses'=>'JwtController@index','middleware'=>'auth:apijwt']);
});
6、取消csrf_token限制
app/http/Middleware
protected $except = [
'/jwt/*'
];
7、测试
98.jpg将这个返回的值复制下来
Route::get('/', ['uses'=>'JwtController@index','middleware'=>'auth:apijwt']);
这个定义了,认证之后才能访问
打开
982.jpg
如果不带token试试
984.jpg
使用header的Authorization header
Authorization: Bearer eyJhbGciOiJIUzI1NiI...
//这里前面加Bearer
985.jpg
jwt参考函数
attempt() //$token = auth()->attempt($credentials);
login()
//user = User::first();
// Get the token
//$token = auth()->login($user);
user() //取得当前认证的用户
userOrFail()
logout()
refresh()
invalidate() :令牌无效
tokenById() :取得token来至user的id
payload()
validate()