Laravel Vue 前后端分離 使用token認證

在做前后臺分離的項目中缓淹,認證是必須的,由于http是無狀態(tài)的。前臺用戶登錄成功后割卖,后臺給前臺返回token前酿。之后前臺給后臺發(fā)請求每次攜帶token。

原理也非常簡單:

  1. 前天在請求頭中添加 Authorization鹏溯,如下


    image.png
  2. 后臺取到值罢维,然后去用戶表的api_token列進行匹配,如果查到說明驗證成功丙挽,并且返回相關(guān)信息肺孵。

Laravel本身自帶幾種驗證方式,下面介紹下token認證的實現(xiàn)的方法颜阐。

前臺在向后臺發(fā)起請求時要攜帶一個token

后臺需要做一個返回當(dāng)前登錄用戶的信息的api平窘,地址是 /api/user

  1. 先添加路由,當(dāng)給 route/api.php 添加
Route::middleware('auth:api')->get('/user', function (Request $request) {
    echo $request->user();
});

如果瀏覽器直接訪問 http://mydomain.com/api/user 會返回 401 Unauthorized
原因是在config/auth.php中有下面的關(guān)鍵配置

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

可以看到通過api訪問走的是token認證凳怨,這里沒有提供token所以就認證失敗返回401了瑰艘。

  1. 'driver' => 'token' 實際調(diào)用的是\vendor\laravel\framework\src\Illuminate\Auth\TokenGuard.php
    上面說到我們需要在request里提供api_token參數(shù),為了區(qū)別是哪個用戶肤舞,需要在user表添加api_token字段
image.png
  1. 認證過程調(diào)用的是getTokenForRequest方法
    public function getTokenForRequest()
    {
        $token = $this->request->query($this->inputKey);

        if (empty($token)) {
            $token = $this->request->input($this->inputKey);
        }

        if (empty($token)) {
            $token = $this->request->bearerToken();
        }

        if (empty($token)) {
            $token = $this->request->getPassword();
        }

        return $token;
    }

這個bearerToken實際找header中是否存在Authorization

    public function bearerToken()
    {
        $header = $this->header('Authorization', '');

        if (Str::startsWith($header, 'Bearer ')) {
            return Str::substr($header, 7);
        }
    }
  1. 先給user表添加api_token字段
    php artisan make:migration add_api_token_to_users --table=users
    內(nèi)容
class AddApiTokenToUsers extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('api_token', 60)->unique();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('api_token');
        });
    }
}
  1. 打開navicat進到user表里紫新,更新users的api_token。


    image.png
  2. 打開postman


    image.png

    注意這里的header李剖,key是Authorization芒率,值就是Bearer+空格+剛才數(shù)據(jù)庫里設(shè)的api_token

這樣就能返回內(nèi)容啦,修改其他用戶的token能返回相應(yīng)的用戶信息篙顺,說明認證成功偶芍,功能基本完成!
下面完善細節(jié)

  1. 完善邏輯
    修改 \app\Http\Controllers\Auth\RegisterController.php
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
            // 添加這行
            'api_token' => str_random(60),
        ]);
    }

User Model 的 $fillable也改下

    protected $fillable = [
        'name', 'email', 'password', 'api_token',
    ];
  1. 如果在前臺頁面德玫,發(fā)起請求時如何給后臺傳這個Authorization header? 方法如下
    注意匪蟀,下面的是Laravel5.4的修改方法。新版本可能有細微區(qū)別化焕,只要知道原理就能自己改了萄窜。

打開 \resources\assets\js\bootstrap.js 參照著csrf-token铃剔。合適的地方添加下面的代碼

let token     = document.head.querySelector('meta[name="csrf-token"]');
let api_token = document.head.querySelector('meta[name="api-token"]');

if (token) {
    // 這個要參考axios的文檔
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = Laravel.csrfToken =token.content;
    // 如果用的jquery
    // Fix jquery ajax crossDomain without Token
    // jQuery.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    //     // if (options.crossDomain) {
    //     jqXHR.setRequestHeader('Authorization', api_token.content);
    //     jqXHR.setRequestHeader('X-CSRF-TOKEN', token.content);
    //     //}
    // });
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}


if (api_token) {
    window.axios.defaults.headers.common['Authorization'] = api_token.content;
} else {
    console.error('Authorization token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

最后修改公共視圖模版中 \views\layouts\app.blade.php

    <meta name="csrf-token" content="{{ csrf_token() }}">
    <meta name="api-token" content="{{ Auth::check() ? 'Bearer '.Auth::user()->api_token : 'Bearer ' }}">

總結(jié):
本質(zhì)上給用戶表添加api_token撒桨,后臺根據(jù)這個字段判斷是否是有效的用戶,無效返回401键兜,有效返回查詢結(jié)果凤类。
優(yōu)點是容易理解,缺點太簡單普气,安全也不夠谜疤。
為了安全,可以實現(xiàn)下面的功能:

  1. 每次登錄成功后刷新api_token為新值
    其實 Laravel 官方提供了一個 Laravel Passport 的包。Laravel Passport is an OAuth2 server and API authentication package 夷磕。
    具體使用請等更新履肃。

問題:
如何修改默認的api_token列?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坐桩,一起剝皮案震驚了整個濱河市尺棋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绵跷,老刑警劉巖膘螟,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碾局,居然都是意外死亡荆残,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門净当,熙熙樓的掌柜王于貴愁眉苦臉地迎上來内斯,“玉大人,你說我怎么就攤上這事像啼『倨冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵埋合,是天一觀的道長备徐。 經(jīng)常有香客問我,道長甚颂,這世上最難降的妖魔是什么蜜猾? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮振诬,結(jié)果婚禮上蹭睡,老公的妹妹穿的比我還像新娘。我一直安慰自己赶么,他們只是感情好肩豁,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辫呻,像睡著了一般清钥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上放闺,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天祟昭,我揣著相機與錄音,去河邊找鬼怖侦。 笑死篡悟,一個胖子當(dāng)著我的面吹牛谜叹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搬葬,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荷腊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了急凰?” 一聲冷哼從身側(cè)響起停局,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎香府,沒想到半個月后董栽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡企孩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年锭碳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勿璃。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡擒抛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出补疑,到底是詐尸還是另有隱情歧沪,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布莲组,位于F島的核電站诊胞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锹杈。R本人自食惡果不足惜撵孤,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竭望。 院中可真熱鬧邪码,春花似錦、人聲如沸咬清。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旧烧。三九已至影钉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粪滤,已是汗流浹背斧拍。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杖小,地道東北人肆汹。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像予权,于是被迫代替她去往敵國和親昂勉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355