国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
API接口JWT方式的Token認(rèn)證(上),服務(wù)器(Laravel)的實現(xiàn)

簡介

最近在開發(fā)一個 Android 程序,需要做用戶登錄和認(rèn)證功能,另外服務(wù)器用的是 Laravel 框架搭建的。最終決定用 JWT 實現(xiàn)API接口的認(rèn)證。

JWT 是 Json Web Tokens 的縮寫,與傳統(tǒng) Web 的 Cookies 或者 Session 方式的認(rèn)證不同的是,JWT 是無狀態(tài)的,服務(wù)器上不需要對 token 進(jìn)行存儲,也不需要和客戶端保持連接。而 JWT 的 token 分3個部分,首先是頭部 ,表明這是一個JWT,并指明加密方式,第二部分是負(fù)載,其中可以包含 賬戶名、ID、郵箱等用戶信息,同時也包含了token到期時間,以 Unix 時間戳的方式記錄,頭部和負(fù)載都會進(jìn)行 base64 編碼,最后一部分是簽名,用來驗證負(fù)載的信息是否正確。

服務(wù)器上會保存一個全局 JWT_SECRET ,用于生成 token 和驗證 token。在用戶登錄成功后,服務(wù)器從數(shù)據(jù)庫獲取用戶的相關(guān)信息,計算出 token 到期時間,生成頭部和負(fù)載并編碼,再將前面的內(nèi)容使用 JWT_SECRET 進(jìn)行加密,生成簽名,最后將3個部分合并返回給客戶端。

客戶端訪問需要認(rèn)證的客戶端時,在 Http 請求頭部加上 Authrization 字段,內(nèi)容為 Bearer 加 token。服務(wù)器收到請求后,利用 JWT_SECRET 驗證 token 是否合法,從負(fù)載中提取到期時間確認(rèn) token 是否過期,再從 token 提取用戶信息,與數(shù)據(jù)庫進(jìn)行對比。如果這些都通過的話就可以進(jìn)行后續(xù)操作了。

這里指大概介紹一下 JWT 的特點和驗證流程,更詳細(xì)的介紹大家可以自行搜索,或者訪問 https://jwt.io/introduction/ 。

先上代碼:
https://github.com/zhongchenyu/jokes-laravel
因為后續(xù)代碼可能會做重構(gòu),本文所介紹的代碼保存在 demo2 分支,請 checkout demo2 。

服務(wù)器代碼實現(xiàn)

我們從一個空的 Laravel 項目開始著手,這里假設(shè)通過 laravel new project_name 命令安裝了一個空的項目,并且完成了初始化配置,已經(jīng)可以訪問一些簡單的測試 API了。下面開始搞 JWT。

1. 安裝 JWT 庫

首先通過 composer 安裝 PHP 的 JWT 庫:
composer require tymon/jwt-auth 0.5.*

在 config/app.php 下添加 JWTAuthServiceProvider:

'providers' => [        /*         * Laravel Framework Service Providers...         */                      ...        Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class    ],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

也是在 config/app.php 下,注冊門面:

'aliases' => [        ...        'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,        'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,    ],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

發(fā)布 JWT 的配置文件到 config/jwt.php :

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

生成 JWT_SECRET,執(zhí)行命令php artisan jwt:generate ,
會在 config/jwt.php 下生成'secret' => env('JWT_SECRET', 'UCDncib***wOY6gj0sD'), ,從 .env 的 JWT_SECRET 取值,如果沒有再取后面的默認(rèn)值,因為 config/jwt.php 是要隨著 Git 版本發(fā)布的,所有最好在不同的環(huán)境上分別執(zhí)行命令來生成 secret ,并且保持到 .env 文件中, .env 文件默認(rèn)是 gitignore 的。

這樣 JWT 庫就安裝好可以使用了。

2. 初始化數(shù)據(jù)庫

首先創(chuàng)建好數(shù)據(jù)庫,并修改 .env 文件中相關(guān)的值:

DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=jokesDB_USERNAME=homesteadDB_PASSWORD=secret
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這是數(shù)據(jù)庫還是空的,沒有任何 table,需要先進(jìn)行數(shù)據(jù)庫遷移。要做用戶認(rèn)證,肯定需要一個用戶表,這個其實 Laravel 在已經(jīng)幫我們做好的,在 database/migrations 下面已經(jīng)生成了遷移文件:

看一下 create_users_table.php 的代碼,創(chuàng)建一個 users 表,包含 id、name、email、password等列。

public function up()    {        Schema::create('users', function (Blueprint $table) {            $table->increments('id');            $table->string('name');            $table->string('email')->unique();            $table->string('password');            $table->rememberToken();            $table->timestamps();        });    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

執(zhí)行php artisan migrate 命令就會在 Jokes 數(shù)據(jù)庫下創(chuàng)建好 users
表了。

mysql> show columns from users;+----------------+------------------+------+-----+---------+----------------+| Field          | Type             | Null | Key | Default | Extra          |+----------------+------------------+------+-----+---------+----------------+| id             | int(10) unsigned | NO   | PRI | NULL    | auto_increment || name           | varchar(255)     | NO   |     | NULL    |                || email          | varchar(255)     | NO   | UNI | NULL    |                || password       | varchar(255)     | NO   |     | NULL    |                || remember_token | varchar(100)     | YES  |     | NULL    |                || created_at     | timestamp        | YES  |     | NULL    |                || updated_at     | timestamp        | YES  |     | NULL    |                |+----------------+------------------+------+-----+---------+----------------+7 rows in set (0.00 sec)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

對應(yīng)的 Model 也已經(jīng)自動創(chuàng)建好了,就是 app/User.php 文件。

3. 實現(xiàn)注冊 API

users table 創(chuàng)建好后,當(dāng)然是要生成 user 數(shù)據(jù)了,可以用 seeder 來生成測試用的 Faker 數(shù)據(jù),初始代碼也基本完成了 users 的 seeder。不過我們直接實現(xiàn)注冊 API,通過 API 來創(chuàng)建數(shù)據(jù)。

在 Routes/api.php 下增加一條路由,這里我們使用的是 Dingo/Api :

$api->post('register', 'Auth\RegisterController@register');
  • 1
  • 1

訪問 register 路徑,會調(diào)用 Auth\RegisterController.php 控制器下的 register 方法,看下代碼:

protected function validator(array $data)    {        return Validator::make($data, [            'name' => 'required|string|max:255',            'email' => 'required|string|email|max:255|unique:users',            'password' => 'required|string|min:6' //|confirmed'         ]);    }    protected function create(array $data)    {        return User::create([            'name' => $data['name'],            'email' => $data['email'],            'password' => bcrypt($data['password']),        ]);    }  public function register(Request $request)  {    $this->validator($request->all())->validate();    $user = $this->create($request->all());    $token = JWTAuth::fromUser($user);    return ["token" => $token];  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

其實大部分代碼 Laravel 已經(jīng)自動生成好了,但是由于原來的代碼是用于 Web 注冊的,注冊成功后會重定向到登錄頁面,但是我們是給 API 做認(rèn)證,所有就把這塊代碼改一下。
validator 方法是用來驗證 Http 請求參數(shù)的。

'name' => 'required|string|max:255' 表示 name 是必須的,并且是最大長度255的字符串。

'email' => 'required|string|email|max:255|unique:users' 表示 email 是必須的,為最長255的郵箱格式的字符串,并且要和 users 數(shù)據(jù)庫中的email不重復(fù)。

'password' => 'required|string|min:6' 表示 password是必須的,為最短6位的字符串,也可以加上 confirmed,表示需要二次確認(rèn),在請求參數(shù)中要在加上 password_confirmation ,并且和 password 是相同的才能通過驗證,這里我們就先不用這個確認(rèn)了。

create 方法將注冊的用戶信息寫到數(shù)據(jù)庫的 users table 中,其中 password 是經(jīng)過加密存儲的。

在 register 方法中, 先調(diào)用 validator,檢查請求參數(shù)是否合法,通過后調(diào)用 create 將此用戶數(shù)據(jù)寫入數(shù)據(jù)庫,在根據(jù)用戶信息生成一個 token,返回給客戶端。

測試一下,注冊成功,返回 token:

mysql> select id,name,email,password from users where email = 'user6@user.com' ;+----+---------+----------------+--------------------------------------------------------------+| id | name    | email          | password                                                     |+----+---------+----------------+--------------------------------------------------------------+|  9 | user666 | user6@user.com | $2y$10$YCj55dl7ByyRP4x6znfM0.6Xsj9ScwF6d5czn1t4RZ59bOQgg0ST6 |+----+---------+----------------+--------------------------------------------------------------+1 row in set (0.00 sec)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4. 實現(xiàn)登錄 API

首先在 Routes/api.php 下添加路由:
$api->get('login', 'Auth\AuthenticateController@authenticate');

看下 Auth\AuthenticateController 下的 authenticate 方法:

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) {      return response()->json(['error' => 'could_not_create_token'], 500);    }    $user = User::where('email', $credentials['email'])->first();    $userTransform = new UserTransformer();    return ['user'=> $userTransform->transform($user), 'token' => $token];     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

代碼也是基本初始化好了的,但是原來的代碼登錄后只返回 token,我們修改下,加上返回 User 信息。
先將 請求中的 email 和 password 存到 $credentials 中,再通過$token = JWTAuth::attempt($credentials) 檢驗 email 和 password,并嘗試轉(zhuǎn)換成 token,如果失敗,則返回異常,如果成功則將 user 和 token 返回。

測試一下,用剛才的賬號登錄,成功獲取到用戶信息和 token:

5. 實現(xiàn) token 認(rèn)證

用戶完成注冊登錄后,獲取到 token,接下來就可以訪問需要認(rèn)證的 API 了,這里我們建一個簡單的 API 來說明認(rèn)證的實現(xiàn)方法。

假設(shè)用戶需要獲取通知信息 notices,服務(wù)器要求必須在登錄后才能獲取。

首先添加路由,這里用到了路由組和中間件(middleware):
在 app/kernel.php 文件下添加路由中間件:

protected $routeMiddleware = [        ...        'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',        'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',    ];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
$api->group(['middleware' => 'jwt.auth', 'providers' => 'jwt'], function ($api) { //    $api->get('user', 'UserController@getUserInfo');    $api->get('notices', 'NoticeController@index');  });
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

此 group 下的所有路由,都需要先通過中間件處理,這里用的是 jwt.auth,及只有通過 jwt 認(rèn)證之后,才能繼續(xù)后面的訪問。

這里只用來測試,NoticeController 下的 index 方法的返回數(shù)據(jù)直接是一句話:

public function index()  {    return ["content" => "This notice can be seen only after Auth"];  }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

測試一下用正確的 token 訪問,在 Header 添加 Authrization 項,記住在 token 前加 Bearer ,可以獲取數(shù)據(jù):

測試用非法 token 訪問,返回400錯誤:

測試過期 token 訪問, 返回401錯誤:

同時我們還添加了 user 路由,JWTAuth::parseToken()->authenticate() 通過 token 獲取用戶:

class UserController extends Controller{  public function getUserInfo(Request $request)  {    $user = JWTAuth::parseToken()->authenticate();    return ( new UserTransformer())->transform($user);  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

請求中添加 Authrization頭,測試,這個 API 不僅用來獲取用戶信息,也作為 客戶端存儲的 token是否有效的檢測 API:

至此,服務(wù)器上的認(rèn)證相關(guān)的 API 接口就都準(zhǔn)備好了,下篇文章將講 android 客戶端的實現(xiàn)。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Laravel 使用 JWT (Json Web Token) 做 API 認(rèn)證之tymon/jwt
【Laravel系列7.4】安全相關(guān)
jwt
說一說幾種常用的登錄認(rèn)證方式,你用的哪種?
微服務(wù)系統(tǒng)之認(rèn)證管理詳解
7000 字 | 32 圖 | 手摸手 Spring Cloud Gateway + JWT 實現(xiàn)登錄認(rèn)證
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服