前後の分離:tokenログインソリューションの使用
8100 ワード
ログイン時にtokenを取得し、後でインタフェースを呼び出すとtokenを連れてサーバに要求します
Tokenログインソリューションを使用した前後の分離
この記事では,前後の分離によるログインソリューションについて述べるが,現在ではほとんどがTokenをリクエストヘッダで携帯する形式を採用している.
書く前にまず考えを整理してください.初回ログイン時、バックエンドサーバはユーザーアカウントのパスワードが正しいと判断した後、ユーザーid、ユーザー名、定義された鍵、期限切れ時間に基づいてtokenを生成し、フロントエンドに戻る. フロントエンドはバックエンドから戻ってきたtokenを受け取り、localStroageとVuexに格納される. フロントエンドはルーティングごとにジャンプし、localStroageにtokenがあるかどうかを判断し、ない場合はログインページにジャンプし、ある場合はユーザー情報の取得を要求し、ログイン状態を変更する. 毎回インタフェースを要求し、Axios要求ヘッダにtokenを携帯する. バックエンドインタフェースは、要求ヘッダがtokenであるか、tokenが期限切れであるかを判断し、401を返す. フロントエンドは401ステータスコードを取得し、ログインページにリダイレクトする.
私のここのフロントエンドはVueを使って、住所:vue-token-login
バックエンドはアリのeggを使用し、アドレス:egg-token-login
まず、Axiosを軽くカプセル化します.
私はTokenをlocalStroageに存在させて、Tokenがあるかどうかを検査して、毎回Axiosリクエストの頭の上で携帯することを要求します
responeブロッカーを用いて,2 xx状態コード以外の結果をブロッキングする.
ステータスコードが401の場合、Tokenが期限切れになり、ログインページにジャンプする可能性があります.
ルーティングの定義:
トップページのルーティングにrequiresAuthを加えたので、ルーティングフックを使用してナビゲーションをブロックし、localStroageにTokenがあればuserInfoを取得する方法を呼び出し、実行を続け、Tokenがなければログインを終了する方法を呼び出し、ログインページにリダイレクトします.
ここでは2つのVuexのactionメソッドを使って、すぐに言います.
Vuex
まず、mutation_typesで定義:
次にmutationで使用します.
Axiosをカプセル化したJSで要求インタフェースを定義します.
Vuexのactionsに導入:
アクションの定義
インタフェース
この時、バックエンドインタフェースを書くべきです.
私はアリのeggフレームを使っていて、強い感じがします.
まず、LoginControllerを定義します.
UserController:
router.jsでインタフェースを定義します.
フロントエンドリクエスト
インタフェースができたので、フロントエンドでお願いします.
ここではログインコンポーネントを書きましたが、ログイン時のloginメソッドをクリックします.
ログインに成功したら、トップページの前にリダイレクトしたページにジャンプします.
全体の流れが走り終わって、実現する主な機能は:ログイン登録以外のルートにアクセスするには、ログイン権限が必要です.例えば、トップページでtokenの有無を判断し、あればアクセスに成功し、なければログインページにジャンプします. ログインに成功した後、前にリダイレクトしたページにジャンプします. tokenが期限切れになった後、インタフェースを要求すると、アイデンティティが期限切れになり、ログインページにジャンプし、2番目のステップを続行します.このステップは主に7日間の自動ログインなどの機能を使用しています.
転載先:http://www.yyyweb.com/5144.html
https://www.cnblogs.com/xiaoyingainiaa/p/9810610.html
Tokenログインソリューションを使用した前後の分離
この記事では,前後の分離によるログインソリューションについて述べるが,現在ではほとんどがTokenをリクエストヘッダで携帯する形式を採用している.
書く前にまず考えを整理してください.
私のここのフロントエンドはVueを使って、住所:vue-token-login
バックエンドはアリのeggを使用し、アドレス:egg-token-login
まず、Axiosを軽くカプセル化します.
私はTokenをlocalStroageに存在させて、Tokenがあるかどうかを検査して、毎回Axiosリクエストの頭の上で携帯することを要求します
if (window.localStorage.getItem('token')) {
Axios.defaults.headers.common['Authorization'] = `Bearer ` + window.localStorage.getItem('token')
}
responeブロッカーを用いて,2 xx状態コード以外の結果をブロッキングする.
ステータスコードが401の場合、Tokenが期限切れになり、ログインページにジャンプする可能性があります.
instance.interceptors.response.use(
response => {
return response
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
router.replace({
path: 'login',
query: { redirect: router.currentRoute.fullPath } // path ,
})
}
}
return Promise.reject(error.response)
}
)
ルーティングの定義:
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Index',
component: Index,
meta: {
requiresAuth: true
}
},
{
path: '/login',
name: 'Login',
component: Login
}
]
})
トップページのルーティングにrequiresAuthを加えたので、ルーティングフックを使用してナビゲーションをブロックし、localStroageにTokenがあればuserInfoを取得する方法を呼び出し、実行を続け、Tokenがなければログインを終了する方法を呼び出し、ログインページにリダイレクトします.
router.beforeEach((to, from, next) => {
let token = window.localStorage.getItem('token')
if (to.meta.requiresAuth) {
if (token) {
store.dispatch('getUser')
next()
} else {
store.dispatch('logOut')
next({
path: '/login',
query: { redirect: to.fullPath }
})
}
} else {
next()
}
})
ここでは2つのVuexのactionメソッドを使って、すぐに言います.
Vuex
まず、mutation_typesで定義:
export const LOGIN = 'LOGIN' //
export const USERINFO = 'USERINFO' //
export const LOGINSTATUS = 'LOGINSTATUS' //
次にmutationで使用します.
const mutations = {
[types.LOGIN]: (state, value) => {
state.token = value
},
[types.USERINFO]: (state, info) => {
state.userInfo = info
},
[types.LOGINSTATUS]: (state, bool) => {
state.loginStatus = bool
}
}
Axiosをカプセル化したJSで要求インタフェースを定義します.
export const login = ({ loginUser, loginPassword }) => {
return instance.post('/login', {
username: loginUser,
password: loginPassword
})
}
export const getUserInfo = () => {
return instance.get('/profile')
}
Vuexのactionsに導入:
import * as types from './types'
import { instance, login, getUserInfo } from '../api'
アクションの定義
export default {
toLogin ({ commit }, info) {
return new Promise((resolve, reject) => {
login(info).then(res => {
if (res.status === 200) {
commit(types.LOGIN, res.data.token) // token
commit(types.LOGINSTATUS, true) //
instance.defaults.headers.common['Authorization'] = `Bearer ` + res.data.token // token
window.localStorage.setItem('token', res.data.token) // localStroage
resolve(res)
}
}).catch((error) => {
console.log(error)
reject(error)
})
})
},
getUser ({ commit }) {
return new Promise((resolve, reject) => {
getUserInfo().then(res => {
if (res.status === 200) {
commit(types.USERINFO, res.data) // userInfo Vuex
}
}).catch((error) => {
reject(error)
})
})
},
logOut ({ commit }) { //
return new Promise((resolve, reject) => {
commit(types.USERINFO, null) // userInfo
commit(types.LOGINSTATUS, false) // false
commit(types.LOGIN, '') // token
window.localStorage.removeItem('token')
})
}
}
インタフェース
この時、バックエンドインタフェースを書くべきです.
私はアリのeggフレームを使っていて、強い感じがします.
まず、LoginControllerを定義します.
const Controller = require('egg').Controller;
const jwt = require('jsonwebtoken'); // jsonwebtoken
class LoginController extends Controller {
async index() {
const ctx = this.ctx;
/*
token , ,
*/
const token = jwt.sign({
user_id: 1, // user_id
user_name: ctx.request.body.username // user_name
}, 'shenzhouhaotian', { //
expiresIn: '60s' //
});
ctx.body = { //
token: token
};
ctx.status = 200; // 200
}
}
module.exports = LoginController;
UserController:
class UserController extends Controller {
async index() {
const ctx = this.ctx
const authorization = ctx.get('Authorization');
if (authorization === '') { // token , 401
ctx.throw(401, 'no token detected in http header "Authorization"');
}
const token = authorization.split(' ')[1];
// console.log(token)
let tokenContent;
try {
tokenContent = await jwt.verify(token, 'shenzhouhaotian'); // token , 401
console.log(tokenContent)
ctx.body = tokenContent // token , userInfo ; ,
} catch (err) {
ctx.throw(401, 'invalid token');
}
}
}
router.jsでインタフェースを定義します.
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/profile', controller.user.index);
router.post('/login', controller.login.index);
};
フロントエンドリクエスト
インタフェースができたので、フロントエンドでお願いします.
ここではログインコンポーネントを書きましたが、ログイン時のloginメソッドをクリックします.
login () {
if (this.username === '') {
this.$message.warning(' ~~')
} else if (this.password === '') {
this.$message.warning(' ~~')
} else {
this.$store.dispatch('toLogin', { // dispatch toLogin action
loginUser: this.username,
loginPassword: this.password
}).then(() => {
this.$store.dispatch('getUser') // dispatch getUserInfo action
let redirectUrl = decodeURIComponent(this.$route.query.redirect || '/')
console.log(redirectUrl)
//
this.$router.push({
path: redirectUrl
})
}).catch((error) => {
console.log(error.response.data.message)
})
}
}
ログインに成功したら、トップページの前にリダイレクトしたページにジャンプします.
全体の流れが走り終わって、実現する主な機能は:
転載先:http://www.yyyweb.com/5144.html
# [ vue token, token header ](https://www.cnblogs.com/xiaoyingainiaa/p/9810610.html)
https://www.cnblogs.com/xiaoyingainiaa/p/9810610.html