iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 2
0
Modern Web

React.js & Laravel 30天訓練系列 第 2

【Day 2】Create Laravel Project & Json Web Token

  • 分享至 

  • xImage
  •  

關於Laravel專案的建立,我想安裝方式都是找的到了
Laravel Get Started

我就不做複製貼上衝版面了~

但是列出幾項安裝環境還有重點項目

  1. Version: 5.1
  2. OS: Windows7

為了不讓PHP安裝的一些東西影響到我原本的.Net環境,我是用Laravel Homestead的Vagrant來控制環境

安裝好之後(我是放在主目錄下面)
你就可以CD到Homestead & vagrant up
https://ithelp.ithome.com.tw/upload/images/20171220/20107767e6yI1XE889.png

Then 看一下裡面的架構,應該就要跟你設定對應本機的資料夾長的一樣
像我設定對應的 Windows Folder 長這樣
https://ithelp.ithome.com.tw/upload/images/20171220/20107767RkfBJTZvMA.png

Vagrant 裡面對應的
https://ithelp.ithome.com.tw/upload/images/20171220/20107767eyELB0488t.png

喔對了你要記得把
C:/Windows/System32/drivers/etc/hosts
這個文件你可以設定你要的URL對應到虛擬機設定的IP
像是我的就這樣設定
https://ithelp.ithome.com.tw/upload/images/20171220/20107767MamsgUOZay.png

做到這邊,如果你是要簡單做個Laravel Hello World什麼的,應該都不是問題,而且最重要的是,你不用擔心電腦環境會被汙染什麼的,反正只是虛擬機,出了事情都可以刪除再重投來過

再來 就是設定Json Web Token
這裡我們不講他到底是什麼底層什麼東西,因為這個你自己可以去外面Google,我也懶得複製貼上

我用他的理由很簡單,因為我把前端跟後端拆成兩個專案
所以API的傳送就要經過驗證,所以我們會在登入之後拿到一組Token,
然後後續的資料拿取要求,就會去做Token的驗證處理。

幾個步驟

  1. 安裝 compose require tymon/jwt-auth

  2. config/app.php 設定
    providers 部分 [..., Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class]
    aliases 部分 [..., 'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class]

  3. 然後產生該產生的東西,像是設定文件檔案或是KEY,記得喔,因為我們是用vagrant,像是接下來的command都是要先vagrant ssh,進去之後才有辦法操作喔,當然啦,如果你外面可以操作的話就代表你外面也有相對應的環境~

文件產生:php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
KEY產生:php artisan jwt:generate

  1. 依照此專案的需求,因為有API的存取需要,所以要做跨源的設定,但是因為我CORS的Middleware是在之前就弄過的,所以我有點忘記我詳細的操作,不過也都是網路上來的,我貼上我 app/Http/Middleware/CORS.php 的程式碼
    public function handle($request, Closure $next)
    {
        header("Access-Control-Allow-Origin: *");

        $headers = [
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin'
        ];
        if ($request->getMethod() == "OPTIONS") {
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach ($headers as $key => $value) {
            $response->header($key, $value);
        }

        return $response;
    }
  1. 然後建立JWT要走的Route,所需要使用的Middleware,意思就是說,來我Server走這些Route的時候,你們手上是要有token的
    5.1 建立Middleware
php artisan make:middleware authJWT

5.2 設定你的 authJWT Middleware

    public function handle($request, Closure $next)
    {
        // dd($request->input('token'));
        try {
            // 如果用户登陆后的所有请求没有jwt的token抛出异常
            $user = JWTAuth::toUser($request->input('token')); 
        } catch (Exception $e) {
            if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
                return response()->json(['error'=>'您的TOKEN已經失效了!']);
            }else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
                return response()->json(['error'=>'您的TOKEN過期了,系統將導至登入頁面!']);
            }else{
                return response()->json(['error'=>$e]);
            }
        }
        return $next($request);
    }
  1. 設定你要走的Route,這裡是我設計時候的想法,如果你有不需要對資料庫做動作的地方,你的Route就要排在JWT驗證以外的Middleware下的Route,例如像是首頁、登入、忘記密碼...
Route::group(['prefix' => 'api'], function () {
	// AuthController ==> With out necessary of Token
	// --- 上線轉換資料方法,之後要把它關掉
    Route::post('TransUserData', 'AuthController@TransUserData');
    // --- 註冊方法
    Route::post('Regist', 'AuthController@Regist');
    Route::post('login', 'AuthController@login');           // 登入
    Route::post('refresh','AuthController@refresh_token');  // 更新Token

    Route::group(['middleware' => 'jwt.auth'], function () {
        Route::post('get_user_details', 'AuthController@get_user_details');  // 用戶詳情
    });
});
  1. 註冊JWT到 app/Http/Kernel.php
    https://ithelp.ithome.com.tw/upload/images/20171220/201077674ZOOT6sC8c.png

到了這裡就要進去Controller 開始處理資料
但是呢,因為我的資料原本是放在SQL,然後我們在上一篇把其轉好了之後,我的User密碼是有加密的
而Laravel JWT預設對應的是一個叫做User的Table
所以我就用他預設的Model app/Http/User.php 去產生我要的模型
然後把我的資料倒進去,記得喔,JWT對密碼的處理方式是用Hash,完整程式碼如下~

    public function TransUserData(Request $request)
    {
        $result = false;
        $msg = "";

        try {

            $UserInfoData = _UserInfo::select('UserID', 'loginEmail', 'loginPW', 'CreatedOn')
                                    ->get()
                                    ->toArray();

            foreach ($UserInfoData as $user) 
            {
                // C方法
                $NewUserData = new _User;
                $NewUserPWD = Hash::make($user['loginPW']);
                $NewUserData->fill(array('email'=>$user['loginEmail'], 'password'=>$NewUserPWD, 'created_at'=>$user['CreatedOn']));
                $NewUserData->save();
            }

            $result = true;
            $msg = "success";
            return response()->json(['result'=>$result, 'message'=>$msg]);

        } catch (Exception $e) {
            $result = false;
            $msg = $e->getMessage();
            return response()->json(['result'=>$result, 'message'=>$msg]);
        }
    }

倒完之後 寫個登入方法來要TOKEN,可以使用POSTMAN 做 HTTP POST的動作喔

    public function login(Request $request)
    {
        $input = $request->all();
        if (!$token = JWTAuth::attempt($input)) {
            return response()->json(['IsSuccess' => false, 'result' => '帳號或密碼有誤唷!']);
        }
        return response()->json(['IsSuccess' => true, 'result' => $token]);
    }

然後再拿著TOKEN來拿資料

    public function get_user_details(Request $request)
    {
        $input = $request->all();
        $user = JWTAuth::toUser($input['token']);
        return response()->json(['result' => $user]);
    }

貼個成果照片
首先是登入
https://ithelp.ithome.com.tw/upload/images/20171220/20107767DM0NzdE7t4.png
然後就會拿到一串TOKEN,再拿它去要USER資料
https://ithelp.ithome.com.tw/upload/images/20171220/20107767GlvinTvAVJ.png

到這裡就差不多囉! 明天開始我們就以這個後端為基礎,來跟前端作互動了。


上一篇
【Day 1】Transfer SQL into MySQL & Initialize Laravel
下一篇
【Day 3】How to Create Reactjs ?
系列文
React.js & Laravel 30天訓練30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
M
iT邦新手 5 級 ‧ 2018-09-01 17:02:32

想請問大大, 如果是打同個接口,想要返回有登入跟沒登入2種不同資料的方法,
假設按下button後 post 出去不經過 jwt的middleware,
請問我可以在controller裡面在判定user有沒有登入嗎?
如果有登入在走jwt的驗證拿取資料, 無登入就給沒有登入的資料。

0
gary_lin
iT邦見習生 ‧ 2018-09-01 17:46:19

從前端發post的時候,你就可以把登入時拿到的token作為參數來驗證用戶有無登入,我是登入後,把token放在local storage裡面,然後要發post的時候再拿來用

我要留言

立即登入留言