Laravel & Vue.js - SPA (9) 修正LoginForm.vue

需求:上一章最後LoginForm.vue中formData內暴露出Passport的ID & Secret

,本章主要是針對這做一些修改

首先先執行命令composer require guzzleHttp (用於PHP中發送HTTP請求)

composer require guzzlehttp/guzzle

次先建立TokenProxy.php 類(用於獲取用戶登入Token及env中的設定),於App\Http\Proxy下

<?php
namespace App\Http\Proxy;
class TokenProxy
{
    protected $http;
    public function __construct(\GuzzleHttp\Client $http)   //引入GuzzleHttp
    {
        $this->http = $http;
    }

    public function login($username,$password)
    {
        //驗證 user email password 以及 is_active
        if(auth()->attempt(['email' => $username,'password' => $password,'is_active' => true]))
        {
            return $this->proxy('password',[
                'username' => $username,
                'password' => $password,
                'scope'    => ''
            ]);
        }
        //驗證錯誤 返回失敗訊息
        return response()->json([
            'status' => false,
            'message' => 'Credentials not match'
        ],421);
    }
    
    public function proxy($grantType,array $data = [])
    {
        $data = array_merge($data,[
            'client_id'     => env('PASSPORT_Client_ID'),
            'client_secret' => env('PASSPORT_Client_Secret'),
            'grant_type'    => $grantType
        ]);
        // oauth/token
        $response = $this->http->post(url('oauth/token'),[
            'form_params' => $data
        ]);
        $token = json_decode((string) $response->getBody(),true);
        return response()->json([
            'token'      => $token['access_token'],
            'expired_in' => $token['expires_in']
        ])->cookie('refreshToken',$token['refresh_token'],21600,null,null,false,true);  
        //60 min * 24 hour * 15 day = 21600 與 AuthServiceProvider內refreshToken過期時間設定一致
    }
}
?>

新增一條API路由

Route::post('/login','Auth\LoginController@login');

修改預設的Auth\LoginController login function

<?php
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Proxy\TokenProxy;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
    use AuthenticatesUsers;
    protected $redirectTo = '/home';
    protected $proxy;                                    //設置proxy變數

    public function __construct(TokenProxy $proxy)       //引入TokenProxy類
    {
        $this->middleware('guest')->except('logout');
        $this->proxy = $proxy;
    }

    //重寫login function
    public function login()
    {
        return $this->proxy->login(request('username'),request('password'));
    }
}
?>

修改LoginForm.vue 修改post路徑 & formData 內容 (這只附上變動的部分)

<script>
    import JWTToken from './../../helpers/jwt';
    export default {
        data() {
            return {
                email:'',
                password:''
            }
        },
        methods:{
            login() {
                let formData = {
                    username : this.email,
                    password : this.password
                };
                axios.post('/api/login',formData).then(response => {
                    console.log(JWTToken.getToken());
                    JWTToken.setToken(response.data.token);
                }).catch(error =>{
                    console.log(error.response.data);
                });
            }
        }
    }
</script>

現在登入Chrome 開發者模式仍會拿到response.data.token,如帳號密碼錯誤則會提示錯誤訊息