1. 程式人生 > >laravel 之jwt認證使用詳解

laravel 之jwt認證使用詳解

.html spa nat var req store ogr doc hcl

轉載 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()

laravel 之jwt認證使用詳解