私はLaravel(5.5)をバックエンドとして使用してVue(2.5)を使用してシングルページアプリケーションを構築しています。ログアウトした後に直接ログインする以外はすべてうまく動作します。この場合、/ api/user(ユーザーのアカウント情報を取得してもう一度ユーザーのIDを確認する)への呼び出しは、401が許可されていないと失敗します(ログインに成功したとしても)。応答として、ユーザーはログイン画面に直接戻されます(私はこの対策を自分で401応答への反応として書きました)。バックエンドにLaravelを使用したVue.js SPAの認証トークンのリフレッシュ
ログアウトするには、ctrl/cmd + Rでページを更新してから、もう一度ログインしてください。ページリフレッシュが私の問題を解決するという事実は、私がX-CSRF-TOKENのリフレッシュを正しく処理していないと信じる理由を与えるか、またはLaravelが使用する特定のクッキーを忘れている可能性があります(hereを参照)。
これは、ユーザーがログインボタンをクリックした後に実行されるログインフォームのコードのスニペットです。
login(){
// Copy the form data
const data = {...this.user};
// If remember is false, don't send the parameter to the server
if(data.remember === false){
delete data.remember;
}
this.authenticating = true;
this.authenticate(data)
.then(this.refreshTokens)
.catch(error => {
this.authenticating = false;
if(error.response && [422, 423].includes(error.response.status)){
this.validationErrors = error.response.data.errors;
this.showErrorMessage(error.response.data.message);
}else{
this.showErrorMessage(error.message);
}
});
},
refreshTokens(){
return new Promise((resolve, reject) => {
axios.get('/refreshtokens')
.then(response => {
window.Laravel.csrfToken = response.data.csrfToken;
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = response.data.csrfToken;
this.authenticating = false;
this.$router.replace(this.$route.query.redirect || '/');
return resolve(response);
})
.catch(error => {
this.showErrorMessage(error.message);
reject(error);
});
});
},
authenticate()
方法はlaravel側のログインエンドポイントを呼び出すvuexアクションです。トークンが再フェッチされた後、ユーザは、(メインページにリダイレクトされ
public function getCsrfToken(){
return ['csrfToken' => csrf_token()];
}
:
/refreshTokensエンドポイントは単純に現在ログインしているユーザーのCSRFトークンを返し、このLaravelコントローラ機能を呼び出しますまたは別のページが指定されている場合) とthis.$router.replace(this.$route.query.redirect || '/');
があり、そこには現在ログインしているユーザーのデータをチェックするために関数が呼び出されます。
この作業を行うために必要な対策はありますか?見落としていますか?
ありがとうございました!
EDIT:すべての役立つ提案した後、2017年11月7日
、私はいくつかの情報を追加したいと思います。私はLaravel側でPassportを使って認証しており、CreateFreshApiTokenミドルウェアが使用されています。
アプリで設定したCookie、特にPassportがJavaScriptアプリケーションからのAPIリクエストを認証するために使用する暗号化されたJWTを保持すると言われているlaravel_token
があります。ログアウトすると、laravel_tokenのクッキーが削除されます。その後すぐに再びログインすると(Axisを使ってAJAXの投稿要求を送信する)、新しいlaravel_token
は設定されていないので、ユーザーを認証しません。私はLaravelがログインPOSTリクエストでクッキーを設定していないが、その後に/ refreshTokens(保護されていない)へのGET要求がの直後にに設定されていることを認識しています。しかし、これは起こっているようには見えません。
私は/refreshTokens
へのリクエストと/api/user
へのリクエストの間の遅延を増やしてみましたが、おそらくサーバーに順番に取得する時間がありましたが、役に立たなかったのです。ここで完全に期すため
は、ログイン要求のサーバー側を処理している私のAuth \ LoginControllerです:
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
// $this->middleware('guest')->except('logout');
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
//return $request->only($this->username(), 'password');
return ['email' => $request->{$this->username()}, 'password' => $request->password, 'active' => 1];
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(\Illuminate\Http\Request $request, $user)
{
$user->last_login = \Carbon\Carbon::now();
$user->timestamps = false;
$user->save();
$user->timestamps = true;
return (new UserResource($user))->additional(
['permissions' => $user->getUIPermissions()]
);
}
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function logout(\Illuminate\Http\Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
}
}
'ログアウト'機能はどのように実装されていますか? – vtosh
ポストリクエストでlaravelのログアウト機能を呼び出します。単に 'axios.post( '/ logout')'; –
ログアウト/ログインのAjaxリクエストが前後に進むのを見ると、新しいトークンが生成され、/ refreshtokensによって返され、その後の(そして失敗した)サーバーへの呼び出しで使用されるトークンが表示されます。 –