laravel - json web token

软件模
• 阅读 4921

Json web token

简称JWT,一个健壮令牌标准-RFC7519
JWT由三部分组成:

  1. header

  2. payload

  3. VERIFY SIGNATURE

header&payload用base64编码,中间用.隔开,重要的是VERIFY SIGNATURE,使用HMAC SHA-256算法生成摘要,具体为

#伪代码
HMACSHA256(
  base64encode(header) + "." + base64Encode(payload) + '.' +secret
)

php中hs256算法:

//algo指定为sha256,数据放data,screat为key
string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )

secret存服务器端,别泄露了。具体了解可参考:JWT.io


Laravel + jwt

这里Token生成的算法及验证就确定下来,和laravel 5.2 搭配使用如下:
laravel - json web token

基本配置

1.安装:composer require tymon/jwt-auth 0.5.*
2.config/app.php中:

  1. provider增加

    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class
  2. aliases 增加

    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class
    

3.发布相应配置文件

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

执行完命令后在config/下会新增jwt配置文件jwt.php:

//file:jwt.php
    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Secret (进行加密算法的时候的secret,这里32位)
    |--------------------------------------------------------------------------
    */

    'secret' => env('JWT_SECRET', 'ZD23ADFVKSKSDFSDJFKDFDFVsafaa12a'),

    /*
    |--------------------------------------------------------------------------
    | JWT time to live (token有效期,单位分钟)
    |--------------------------------------------------------------------------
    | Defaults to 1 hour
    | 1 hour = 60 minutes
    */

    'ttl' => 60,

    /*
    |--------------------------------------------------------------------------
    | Refresh time to live (刷新token时间,单位分钟)
    |--------------------------------------------------------------------------
    | Defaults to 2 weeks
    | 2 weeks = 20160 minute
    */

    'refresh_ttl' => 20160,

    /*
    |--------------------------------------------------------------------------
    | JWT hashing algorithm (token签名算法)
    |--------------------------------------------------------------------------
    */

    'algo' => 'HS256',

    /*
    |--------------------------------------------------------------------------
    | User Model namespace (指向User模型的命名空间路径)
    |--------------------------------------------------------------------------
    */

    'user' => 'App\Models\User',

    /*
    |--------------------------------------------------------------------------
    | User identifier (用于从token的sub中获取用户)
    |--------------------------------------------------------------------------
    |
    */

    'identifier' => 'id',

    /*
    |--------------------------------------------------------------------------
    | Required Claims (必须出现在token的payload中的选项,否则会抛出TokenInvalidException异常) 
    |--------------------------------------------------------------------------
    |
    */

    'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'],

    /*
    |--------------------------------------------------------------------------
    | Blacklist Enabled (如果该选项被设置为false,那么我们将不能废止token,即使我们刷新了token,前一个token仍然有效)
    |--------------------------------------------------------------------------
    */

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    |--------------------------------------------------------------------------
    | Providers (完成各种任务的具体实现,有需求的情况写可重写)
    |--------------------------------------------------------------------------
    */

    'providers' => [


        'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter',

        'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter',

        'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter',

        'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter',

    ],

];

4.最后生成密钥secret,写入config/jwt.phpJWT_SECRET的value

php artisan jwt:generate

生成token

1.控制器中创建token,使用orm获取用户对象:

$userObj = User::where('email',$username)->first();
$res['token'] = JWTAuth::fromUser($userObj);

2.客户端获取到token,可写入localstorage,正常会话周期每次请求带上,token放入header中:Authorization : Bearer {token},这里的bearer有持票人的意思,token两边的{}必须有。

在apache下会有header被丢弃的情况,apache下得写配置

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

验证

因为接口多,放到路由群组用中间件过滤(中间件姿势如使用不正确请指出):
1.执行php artisan make:middleware verifyToken,在app\Http\Middleware\verifyToken.php会生成verifyToken前置中间件,填充代码如下:

namespace App\Http\Middleware;

use Closure;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class verifyToken
{
    /**
     * 请求前置中间件
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        try {
            if (!JWTAuth::parseToken()->authenticate()) {
                return response()->json(['user_not_found'], 404);
            }
        } catch (TokenExpiredException $e) {
            //toke失效,response code可自定义
            return response()->json(['token_expired'], 405);
        } catch (TokenInvalidException $e) {
            return response()->json(['token_invalid'], $e->getStatusCode());
        } catch (JWTException $e) {
            return response()->json(['token_absent'], $e->getStatusCode());
        }
        return $next($request);
    }
}

2.app\Http\Kernel.php中在routeMiddleware处注册中间件,

'verifyToken' => 'App\Http\Middleware\verifyToken'

3.路由群组中使用:

//群组中中间件可以用多个,用数组传入即可
//这里的fetchResponse是后置中间件,用于包装供cors跨域的几个header
Route::group(['middleware' => ['fetchResponse','verifyToken']],function(){
    Route::match(['POST','OPTIONS'],'someDo','someController@someFunc');
})

4.客户端可根据响应码不同进行处理。完。

参考链接:
1.Github jtw-auth
2.Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证 - laravel学院
3.JWT安全问题-翻译 2015年

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
4年前
JWT的优点和实现Token认证的安全问题
JWT的优点和实现Token认证的安全问题一、什么是JWTJWT——Jsonwebtoken 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态、分布式的Web应用授权。二、我们为什么需要JWT?
Wesley13 Wesley13
4年前
.NET & JWT
使用JWT库JWT,aJWT(JSONWebToken)implementationfor.NET该库支持生成和解析JSONWebToken(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Ftools.ietf.org%2Fhtml%2Fdr
Stella981 Stella981
4年前
Spring Boot 整合 JWT
1、JWT是什么?JWT是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方之间以JSON对象的形式安全传递信息的方法。JWT可以使用HMAC算法或者是RSA的公钥密钥对进行签名。简单来说,就是通过一定规范来生成token,然后可以通过解密算法逆向解密token,这样就可以获取用户信息。优点:1)生产的t
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
4年前
JWT验证机制【刘新宇】【Django REST framework中使用JWT】
JWT在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用JsonWebToken认证机制。什么是JWTJsonwebtoken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519(https:/
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
4年前
Spring Security OAuth 2.0 发放令牌接口地址自定义
OAuth2.0如何获取令牌以密码模式为例,获取TokencurllocationrequestPOST'http://oauthserver/oauth/token'\header'Authorization:BasicdGVzdDp0ZXN0'\
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Stella981 Stella981
4年前
Django REST framework JWT学习
1.JWT学习在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用JsonWebToken认证机制。Jsonwebtoken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519).该token被设计为紧凑且安全的,