轉載 http://www.heibaiketang.com/blog/show/3.html
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、測試
將這個返回的值復制下來
Route::get('/', ['uses'=>'JwtController@index','middleware'=>'auth:apijwt']);
這個定義了,認證之后才能訪問
打開
如果不帶token試試
使用header的Authorization header
Authorization: Bearer eyJhbGciOiJIUzI1NiI...
//這里前面加Bearer
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()