若是您以爲咱們寫得還不錯,記得 點贊 + 關注 + 評論 三連,鼓勵咱們寫出更好的教程💪
若是你想在小程序裏面打造支持微信登陸的企業級用戶系統,能夠學習圖雀社區另一篇文章:Taro 小程序開發大型實戰(九):使用 Authing 打造具備微信登陸的企業級用戶系統javascript
在以前的迷你電商應用中,咱們的網站缺乏了一個關鍵組成部分:用戶鑑權系統,包括登陸、註冊、以及權限管理等相應的配置。徒手實現這些功能當然可行,可是對於一支崇尚精益的團隊來講,選擇可靠的身份認證服務(IDaaS)是更加明智的選擇,不只可以提供完善且豐富的身份認證和用戶鑑權功能,還確保遵循最佳安全實踐和優秀的可擴展性。在這篇教程中,咱們將手把手帶你在本系列以前完成的迷你電商應用中快速集成 Authing 用戶認證模塊,提供一致、流暢、安全的身份認證體驗。html
首先咱們先來看一下總體用戶系統接入後的效果:前端
瞭解了效果以後,咱們爲你準備好了重構以後的迷你電商代碼,你能夠 Clone 這份代碼,而後跟着教程,補充集成用戶系統須要的:vue
git clone -b auth-start https://github.com/tuture-dev/vue-online-shop-frontend.git # 或者下載 Gitee 上的倉庫 git clone -b auth-start https://gitee.com/tuture/vue-online-shop-frontend.git
代碼下載後,在 client/src/pages
目錄中建立 user
目錄,在接下來時間咱們會在其中實現全部與用戶系統相關的頁面。java
提示
本篇教程採用的是 Vue 2.x 版本,但這篇教程的核心是經過 Authing 集成用戶系咱們並無使用太多關於 Vue 的知識。
首先,咱們在 user
頁面目錄下建立 Index.vue
用戶首頁組件,代碼以下:ios
<template> <div> <div class="container"> <div class="container"> <h1 class="user-title"> <router-link to="/" tag="div">登陸/註冊</router-link> </h1> <router-view /> </div> </div> </div> </template> <style> .user-title:hover { cursor: pointer; } .container { margin-top: 40px; } </style>
接着建立 Login.vue
登陸組件,代碼以下:git
<template> <div id="login-form">用戶登陸</div> </template> <script> export default {}; </script>
而後建立 Setting.vue
設置組件,代碼以下:github
<template> <div>settings</div> </template> <script> export default { data() { return { model: { manufacturer: { name: "", _id: "" } } }; }, mounted() {} }; </script>
最後是在路由中集成上面定義的用戶系統相關頁面,修改 client/src/router/index.js
代碼以下:web
// ... import UserIndex from "@/pages/user/Index"; import Login from "@/pages/user/Login"; import Setting from "@/pages/user/Setting"; Vue.use(Router); const router = new Router({ routes: [ { path: "/", name: "Home", component: Home }, { path: "/admin", name: "Admin", component: Index, children: [ { path: "new", name: "New", component: New }, { path: "", name: "Products", component: Products }, { path: "edit/:id", name: "Edit", component: Edit }, { path: "manufacturers", name: "Manufacturers", component: Manufacturers }, { path: "manufacturers/new", name: "NewManufacturers", component: NewManufacturers }, { path: "manufacturers/edit/:id", name: "EditManufacturers", component: EditManufacturers } ] }, { path: "/cart", name: "Cart", component: Cart }, { path: "/detail/:id", name: "Detail", component: Detail }, { path: "/user", name: "User", component: UserIndex, children: [ { path: "login", name: "Login", component: Login }, { path: "settings", name: "Settings", component: Setting } ] } ] }); export default router;
把項目跑起來,點擊右上角的登陸或註冊應該能夠成功地跳轉到登陸頁面(雖然如今還很簡陋哈):vuex
OK,接下來讓咱們具體地實現各個頁面吧~
在這一步驟中,咱們將正式使用 Authing 接入用戶系統。Authing 是國內出色的身份認證雲,能讓咱們輕鬆集成身份認證相關的邏輯,對於我的開發者來講,其無償使用額度也是至關充足的。
首先,讓咱們訪問 Authing 官方網站,點擊右上角的登陸按鈕,以下圖所示:
進入到登陸頁面後,咱們輸入賬戶名和密碼,會直接爲咱們建立賬號:
進入到控制檯後,讓咱們建立一個新的用戶池(顧名思義,就是用來管理和存儲一系列用戶的數據和信息),以下圖所示:
在建立用戶池的時候,輸入咱們想要的用戶池名稱和專屬域名後,選擇類型爲 Web,最後點擊,咱們的第一個用戶池邊建立好了。點擊「基礎配置」書籤,能夠查看到剛纔建立用戶池的一些關鍵信息,特別是用戶池 ID,以下圖所示:
注意
後續應用開發時,全部的用戶池 ID(userPoolId
)請替換成本身賬戶的真實 ID。
因爲咱們的應用使用了 Vuex 來解決狀態管理問題,所以咱們首先須要定義身份驗證相關的 Mutation。這裏咱們定義兩個新的 Mutation:
SET_USER
:設置用戶身份數據LOGOUT
:退出登陸在 client/src/store/mutation-types.js
中添加上面三個 Mutation 常量,代碼以下:
export const ALL_PRODUCTS = "ALL_PRODUCTS"; export const ALL_PRODUCTS_SUCCESS = "ALL_PRODUCTS_SUCCESS"; export const PRODUCT_BY_ID = "PRODUCT_BY_ID"; export const PRODUCT_BY_ID_SUCCESS = "PRODUCT_BY_ID_SUCCESS"; export const ADD_PRODUCT = "ADD_PRODUCT"; export const ADD_PRODUCT_SUCCESS = "ADD_PRODUCT_SUCCESS"; export const UPDATE_PRODUCT = "UPDATE_PRODUCT"; export const UPDATE_PRODUCT_SUCCESS = "UPDATE_PRODUCT_SUCCESS"; export const REMOVE_PRODUCT = "REMOVE_PRODUCT"; export const REMOVE_PRODUCT_SUCCESS = "REMOVE_PRODUCT_SUCCESS"; export const ADD_TO_CART = "ADD_TO_CART"; export const REMOVE_FROM_CART = "REMOVE_FROM_CART"; export const ALL_MANUFACTURERS = "ALL_MANUFACTURER"; export const ALL_MANUFACTURERS_SUCCESS = "ALL_MANUFACTURER_S"; export const MANUFACTURER_BY_ID = "MANUFACTURER_BY_ID"; export const MANUFACTURER_BY_ID_SUCCESS = "MANUFACTURER_BY_ID_SUCCESS"; export const ADD_MANUFACTURER = "ADD_MANUFACTURER"; export const ADD_MANUFACTURER_SUCCESS = "ADD_MANUFACTURER_SUCCESS"; export const UPDATE_MANUFACTURER = "UPDATE_MANUFACTURER"; export const UPDATE_MANUFACTURER_SUCCESS = "UPDATE_MANUFACTURER_SUCCESS"; export const REMOVE_MANUFACTURER = "REMOVE_MANUFACTURER"; export const REMOVE_MANUFACTURER_SUCCESS = "REMOVE_MANUFACTURER_SUCCESS"; export const SET_USER = "SET_USER"; export const UPDATE_USER = "UPDATE_USER"; export const LOGOUT = "LOGOUT";
而後咱們在 client/src/store/mutations.js
中實現上面定義用戶相關 Mutation,代碼以下:
// ... UPDATE_MANUFACTURER_SUCCESS, REMOVE_MANUFACTURER, REMOVE_MANUFACTURER_SUCCESS, SET_USER, UPDATE_USER, LOGOUT } from "./mutation-types"; import { Message } from "element-ui"; export const userMutations = { [SET_USER](state, payload) { state.user = payload; }, [LOGOUT](state) { state.user = {}; } }; export const productMutations = { [ALL_PRODUCTS](state) { // ... state.showLoader = false; const { productId } = payload; state.products = state.products.filter( product => product._id !== productId ); }, [UPDATE_PRODUCT](state) { state.showLoader = true; // ... const { product: newProduct } = payload; state.product = newProduct; state.products = state.products.map(product => { if (product._id === newProduct._id) { return newProduct; } // ... const { product } = payload; state.cart.push(product); Message({ message: "恭喜你,成功加入購物車!", type: "success" }); }, [REMOVE_FROM_CART](state, payload) { const { productId } = payload; state.cart = state.cart.filter(product => product._id !== productId); Message({ message: "恭喜你,成功移除購物車!", type: "success" }); } }; export const manufacturerMutations = { // ... state.showLoader = false; const { manufacturerId } = payload; state.manufacturers = state.manufacturers.filter( manufacturer => manufacturer._id !== manufacturerId ); }, [UPDATE_MANUFACTURER](state) { state.showLoader = true; // ... const { manufacturer } = payload; state.manufacturers = state.manufacturers.concat(manufacturer); } };
最後咱們在 Vuex Store 中集成相應的狀態與 Mutation,修改 client/src/store/index.js
,代碼以下:
// ... import { productGetters, manufacturerGetters } from "./getters"; import { productMutations, cartMutations, manufacturerMutations, userMutations } from "./mutations"; import { productActions, manufacturerActions } from "./actions"; Vue.use(Vuex); export default new Vuex.Store({ strict: true, state: { // ... // userInfo user: {} }, mutations: { ...productMutations, ...cartMutations, ...manufacturerMutations, ...userMutations }, // ... });
讓咱們打開根組件 client/src/App.vue
,在其中添加一個 mounted
方法,使得在整個應用剛啓動時獲取並檢查用戶身份數據。修改代碼以下:
// ... <script> export default { name: "App", mounted() { const userInfo = localStorage.getItem("userInfo"); if (userInfo) { this.$store.commit("SET_USER", JSON.parse(userInfo)); } } }; </script> // ...
能夠看到,咱們從 localStorage
中檢查是否有 userInfo
數據,若是有的話經過 SET_USER
Mutation 將用戶身份數據存入狀態中。
打開頭部組件 client/src/components/Header.vue
,咱們在其中添加用戶系統相關的邏輯,修改代碼以下:
// ... <script> export default { props: ["activeIndex"], data() { return { model: { manufacturer: { name: "", _id: "" } } }; }, computed: { isLogged() { let token = this.$store.state.user.token; return !!token; }, avatar() { let photo = this.$store.state.user.photo; return photo; } }, methods: { handleLogout() { localStorage.removeItem("token"); localStorage.removeItem("userInfo"); this.$store.commit("LOGOUT"); } } }; </script>
能夠看到,咱們主要作了如下改變:
isLogged
從原先的 data
變成了一個計算屬性,經過從 Vuex Store 中獲取 token
是否存在來判斷是否登陸avatar
計算屬性,用於從 Store 中獲取用戶頭像handleLogout
方法,用於處理登出邏輯,包括從 localStorage
中去除 token
和 userInfo
數據,併發起一個 LOGOUT
Mutation 用於更新 Store 的狀態Guard 是 Authing 推出的可嵌入登陸表單,可以讓咱們用幾行代碼爲整個應用集成登陸和註冊功能,集成後的效果以下:
總體效果仍是很 OK 的,並且咱們能夠經過一些配置項輕鬆實現定製,下面咱們就來看看怎麼實現吧。
首先,咱們經過引入 Authing UMD 構建文件來集成 Authing Guard。在 client/index.html
文件中經過 script
標籤引入:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>vue-online-shop</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> <script src="https://cdn.jsdelivr.net/npm/@authing/guard/dist/Guard.umd.min.js"></script> </body> </html>
接着打開登陸頁面組件 client/src/pages/user/Login.vue
,修改代碼以下:
<template> <div id="login-form"></div> </template> <script> export default { data() { return { model: { manufacturer: { name: "", _id: "" } } }; }, mounted() { const appId = ""; const userPoolId = ""; const domain = "https://tuture-first.authing.co"; const form = new Guard(userPoolId, { logo: "https://tuture.co/images/avatar.png", title: "圖雀全棧迷你電商", mountId: "login-form", hideClose: true }); const that = this; form.on("authenticated", userInfo => { that.$store.commit("SET_USER", userInfo); localStorage.setItem("token", JSON.stringify(userInfo.token)); localStorage.setItem("userInfo", JSON.stringify(userInfo)); that.$router.push("/"); }); } }; </script>
咱們在 mounted
生命週期方法中初始化 Guard
實例。在初始化 Guard
實例時,第一個參數是用戶池 ID(記得換成本身的用戶池 ID!),能夠經過 Authing 控制檯獲取,第二個參數則是 Guard 組件的一些選項參數:
logo
是咱們整個網站的 Logo 圖片連接title
是整個登陸表單的標題mountId
是用於掛載登陸表單的 DOM ID,這裏就是模板中惟一的 div
元素 login-form
hideClose
用於隱藏關閉按鈕,由於咱們把登陸作成了一個獨立的頁面,不但願用戶把登陸表單關掉(這樣整個頁面就一片空白啦)提示
關於Guard
完整的構造函數 API,請參考 官方文檔。
在初始化 Guard
組件後,咱們還須要添加身份驗證成功後的監聽事件函數,即 form.on("authenticated", handler)
。能夠看到,在回調函數中,咱們作了三件事:
SET_USER
Mutation,修改 Store 狀態localStorage
中存儲登陸後獲取的用戶信息$router
路由重定向到首頁提示
更多回調事件,可參考 完整事件列表。
配置完成後,開啓應用,點擊登陸按鈕,就能夠看到咱們炫酷的登陸頁面了:
看上去很不錯!
在這一步中,咱們將配置權限管理和路由守衛。權限管理很容易理解,就是當用戶進行某些須要登陸的操做(例如添加到購物車)時判斷是否已經登陸,若是未登陸則重定向到登陸頁面。所謂路由守衛(或稱導航守衛),就是在進入一個具體的路由(頁面)以前,判斷用戶是否具有足夠的權限,若是權限不夠,則直接重定向到登陸頁面,不然容許進入該頁面。
在咱們的應用中,主要有三個地方須要配置權限:
讓咱們逐個擊破吧。
首先,咱們須要爲商品添加按鈕配置權限管理。打開 client/src/components/products/ProductButton.vue
組件,修改 methods
中的 addToCart
和 removeFromCart
方法,代碼以下:
// ... <script> export default { // ... methods: { addToCart() { const token = localStorage.getItem("token"); const that = this; if (token) { this.$store.commit("ADD_TO_CART", { product: this.product }); } else { this.$confirm( "你還未登陸,點擊去登陸跳轉登陸頁面,點擊取消回到主界面", "提示", { confirmButtonText: "去登陸", cancelButtonText: "取消", type: "warning" } ) .then(() => { that.$router.push("/user/login"); }) .catch(() => { this.$message({ type: "info", message: "你已取消" }); }); } }, removeFromCart(productId) { const token = localStorage.getItem("token"); const that = this; if (token) { this.$store.commit("REMOVE_FROM_CART", { productId }); } else { this.$alert( "點擊去登陸跳轉登陸頁面,點擊取消回到主界面", "你還未登陸", { confirmButtonText: "去登陸", cancelButtonText: "取消" } ) .then(() => { that.$router.push("/user/login"); }) .catch(() => { this.$message({ type: "info", message: "你已取消" }); }); } } } }; </script>
能夠看到,實現權限管理的思路很簡單:先從 localStorage
中判斷用於鑑權的 token
是否存在,若是存在則代表已登陸,執行相應的 Mutation;若是不存在 token
,則彈出 Alert 提示框詢問用戶是否須要跳轉到登陸頁面進行登陸。
而後咱們來實現購物車的路由守衛。幸運的是,Vue Router 已經爲咱們提供了組件級別的路由守衛的方法 beforeRouteEnter
。打開 client/src/pages/Cart.vue
,修改代碼以下:
// ... <script> // ... export default { name: "home", // ... beforeRouteEnter(to, from, next) { const token = localStorage.getItem("token"); if (!token) { next("/user/login"); } else { next(); } } }; </script>
依然是經過 localStorage
中嘗試獲取 token
來判斷登陸狀態,而後經過 next
函數進入合適的路由。
相似地,咱們實現後臺管理頁面的路由守衛。打開 client/src/pages/admin.Index.vue
,添加路由守衛方法,代碼以下:
// ... <script> // ... export default { // ... beforeRouteEnter(to, from, next) { const token = localStorage.getItem("token"); if (!token) { next("/user/login"); } else { next(); } } }; </script>
完成這一步後,打開應用,咱們來看一下添加了權限管理和路由守衛的以後的應用會是怎麼樣的:
僅僅實現登陸和註冊功能是遠遠不夠的,咱們還須要將用戶系統集成到現有的數據庫中。例如咱們在添加商品時,但願可以和具體的用戶綁定。
所幸咱們使用的是 MongoDB 數據庫,所以不像傳統的關係型數據庫那樣須要繁雜的表結構更新,只需修改數據模型定義便可。
首先讓咱們來更新一波 Mongoose 數據定義。打開 server/model/index.js
,修改代碼以下:
// ... const productSchema = Schema({ id: ObjectId, name: String, image: String, price: String, description: String, user: String, manufacturer: { type: ObjectId, ref: "Manufacturer" }, }); const manufacturerSchema = Schema({ id: ObjectId, name: String, user: String, }); // ...
能夠看到,咱們主要是在兩個數據模型 productSchema
和 manufacturerSchema
中加入了 user
字段,其餘均無需改變。
接着咱們修改項目的 Action,主要是在兩個新增數據的 Action(addProduct
和 addManufacturer
)建立模型時記錄用戶數據。打開 client/src/store/actions.js
,修改代碼以下:
// ... export const productActions = { // ... addProduct({ commit, state }, payload) { commit(ADD_PRODUCT); const { product } = payload; const _id = state.user._id; axios .post(`${API_BASE}/products`, { ...product, user: _id, manufacturer: product.manufacturer._id }) .then(response => { // ... }) .catch(() => { // ... }); } }; export const manufacturerActions = { // ... addManufacturer({ commit, state }, payload) { commit(ADD_MANUFACTURER); const { manufacturer } = payload; const _id = state.user._id; axios .post(`${API_BASE}/manufacturers`, { ...manufacturer, user: _id }) .then(response => { // ... }) .catch(() => { // ... }); } };
這裏咱們在前端發起請求建立新數據時,把 user
的 _id
也傳了進去,這樣數據庫裏面對應的商品和製造商就會記錄相應的用戶 ID 啦。
在最後一步中,咱們將藉助 Authing SDK 實現更細粒度的用戶身份管理,以及我的信息設置頁面。首先用 npm 安裝 Authing 的 JavaScript SDK:
npm install authing-js-sdk
首先,讓咱們修改 Header 頭部中的賬戶設置連接。打開 client/src/components/Header.vue
,修改代碼以下:
<template> <div class="header"> // ... <div class="header-right"> <el-dropdown v-if="isLogged"> <el-avatar class="el-dropdown-link" :src="avatar"></el-avatar> <el-dropdown-menu slot="dropdown"> <el-dropdown-item> <router-link to="/user/settings" tag="div">帳戶設置</router-link> </el-dropdown-item> <el-dropdown-item> <div @click="handleLogout">退出登陸</div> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> // ... </div> </div> </template> // ... <script> import Authing from "authing-js-sdk"; export default { // ... methods: { async handleLogout() { const userPoolId = ""; const token = JSON.parse(localStorage.getItem("token")); const userId = JSON.parse(localStorage.getItem("userInfo"))._id; const authing = new Authing({ userPoolId }); try { const res = await authing.checkLoginStatus(token); console.log("res", res); await authing.logout(userId); this.$message({ message: "成功登出", type: "success" }); } catch (err) { console.log("err", err); } localStorage.removeItem("token"); localStorage.removeItem("userInfo"); this.$store.commit("LOGOUT"); } } }; </script>
能夠看到,咱們主要作了兩點變更:
/user/settings
路由,這個咱們後面立刻會實現handleLogout
方法中,咱們在 localStorage
抹去用戶信息以前,經過 authing.checkLoginStatus
檢查登陸狀態,而後經過 authing.logout
執行登出操做打開以前已經建立好的設置頁面 client/src/pages/user/Setting.vue
,實現用戶我的信息設置頁面,代碼以下:
<template> <div> <app-header></app-header> <div class="user-container"> <div class="user-form"> <el-upload class="avatar-uploader" action="https://imgkr.com/api/files/upload" :show-file-list="false" :on-success="handleAvatarSuccess" > <img v-if="imageUrl" :src="imageUrl" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> <el-form :model="user" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" > <el-form-item label="暱稱" prop="nickName"> <el-input v-model="user.nickname"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')" >更新</el-button > </el-form-item> </el-form> </div> </div> </div> </template> <style> .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409eff; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } .user-form { width: 500px; } .user-container { display: flex; flex-direction: row; justify-content: center; } </style> <script> import Header from "@/components/Header.vue"; import Authing from "authing-js-sdk"; export default { data() { return { user: {}, imageUrl: "", rules: { nickname: [ { required: true, message: "請輸入你的暱稱", trigger: "blur" }, { min: 3, max: 25, message: "長度在 3 到 25 個字符", trigger: "blur" } ] } }; }, created: function() { const user = this.$store.state.user; const userInfo = localStorage.getItem("userInfo"); if (user && Object.keys(user).length === 0 && userInfo) { this.user = JSON.parse(userInfo); this.imageUrl = this.user.photo; } else { this.user = { ...user }; this.imageUrl = user.photo; } }, components: { "app-header": Header }, methods: { async handleAvatarSuccess(res, file) { if (res.code === 200) { this.imageUrl = res.data; } else { this.$message.error("圖片上傳失敗"); } }, async submitForm(formName) { const nickname = this.user.nickname; const photo = this.imageUrl; const userId = this.user._id; const user = this.user; const that = this; this.$refs[formName].validate(async valid => { if (valid) { const token = localStorage.getItem("token"); const userPoolId = ""; const authing = new Authing({ userPoolId }); const login = await authing.login({ email: "", password: "" }); console.log("nickName", nickname); try { await authing.update({ _id: login._id, photo, nickname }); const newUser = { ...user, nickname, photo }; localStorage.setItem("userInfo", JSON.stringify(newUser)); that.$store.commit("SET_USER", newUser); this.$message({ message: "修改信息成功", type: "success" }); } catch (err) { console.log("err", err); this.$message.error("修改信息失敗"); } } else { console.log("error submit!!"); return false; } }); } } }; </script>
咱們主要看一下 script
和 template
部分。首先在 script
部分中,咱們的組件包括:
data
字段定義了模板中所須要的數據,包括 user
、imageUrl
(頭像連接)以及 rules
(表單校驗規則)created
生命週期方法用於從 Vuex Store 以及 localStorage
中獲取用戶數據(localStorage
的優先級更高一些),而後初始化上面的 data
字段components
用於指定 app-header
組件爲咱們剛纔修改好的 Header
組件methods
中定義了 handleAvatarSuccess
和 submitForm
兩個 Handler,分別用於處理頭像上傳成功以及提交表單的邏輯。在 submitForm
方法中,咱們先從表單中獲取到相應的數據,而後經過 authing.update
更新用戶數據,成功後再修改 Vuex Store 中的狀態讓咱們調整一下 App 根組件。打開 client/src/App.vue
,修改代碼以下:
// ... <script> import Authing from "authing-js-sdk"; export default { name: "App", mounted() { this.checkLogin(); }, methods: { async checkLogin() { const token = localStorage.getItem("token"); if (token) { const userPoolId = ""; const authing = new Authing({ userPoolId }); const result = await authing.checkLoginStatus(JSON.parse(token)); if (result.status) { const userInfo = localStorage.getItem("userInfo"); if (userInfo) { this.$store.commit("SET_USER", JSON.parse(userInfo)); } } else { localStorage.removeItem("token"); localStorage.removeItem("userInfo"); } } } } }; </script> // ...
能夠看到,咱們主要實現了一個 checkLogin
方法,用於在整個應用剛掛載時檢查登陸狀態,若是登陸成功,則從 storage
裏面取出數據並設置進 Redux Store ,若是登陸失效,則清空本地的 storage
信息。
最後咱們調整一下其餘頁面的一些細節。修改 client/src/pages/user/Index.vue
,代碼以下:
<template> <div> <div class="container"> <router-view /> </div> </div> </template> <style></style>
繼續修改 client/src/pages/user/Login.vue
,代碼以下:
<template> <div> <h1 class="user-title"> <router-link to="/" tag="div">用戶界面</router-link> </h1> <div id="login-form"></div> </div> </template> <style> .user-title:hover { cursor: pointer; } </style> // ...
當保存上面的修改的代碼,咱們能夠看到以下的效果:
經過上述流程,咱們就完成了一個完整的用戶系統及其與現有系統的整合,可是有同窗發現了,咱們在平時生活或工做中,除了常規的手機號+驗證碼、郵箱密碼等,還會有一些更方便的登陸方式,如微信登陸、QQ登陸等,那麼咱們如何集成這些方便的登陸呢?實際上可能看起來很複雜,可是在咱們現有的基礎上,用 Authing 能夠很方便的集成微信、QQ登陸等。
注意
只有企業才能集成微信或 QQ 登陸,若是你是我的開發者,那麼這一節你能夠跳過哦🤓
首先去微信官方文檔完成註冊,而後申請一個微信網頁應用,而後獲取到微信網頁應用的 AppID 和 AppSecret:
接着滑動到底部,將受權回調域改成 oauth.authing.cn
而後咱們開始去 Authing 控制檯,在相應微信登陸裏面,填入剛剛獲取的 AppID
和 AppSecret
:
注意到上面咱們第三個參數 「重定向地址」 填寫了咱們如今 Vue 全棧電商應用的開發服務器地址,讀者應該根據本身當前的須要地址進行對應的填寫。
大功告成,經過上面的步驟咱們就配置好了微信網頁登陸,如今你應該能夠看到以下的效果:
個人天!好神奇!就是上面幾下手工點按配置,咱們就集成好了微信登陸!😅
按照和接入微信網頁登陸相似的方式,咱們前往 QQ 互聯中心,註冊一個帳號,並建立一個網頁應用。
而後進入網頁應用,將受權回調地址填寫爲:[https://oauth.authing.cn/oauth/qq/redirect](https://oauth.authing.cn/oauth/qq/redirect)
,接着回到 Authing 控制檯,咱們配置 QQ 登陸:
保存以後,大功告成!咱們的應用裏面就有了 QQ 登陸,和微信登陸一樣簡單!
最後咱們再來嘗試集成一下開發者比較喜好的 Github 登陸,看看 Authing 是如何簡化這一勞動的呢?
首先根據 Github 指引,建立一個 OAuth 應用。
而後填入以下內容:
其中紅框框出來的內容須要填入 Authing 相關的 [https://oauth.authing.cn/oauth/github/redirect](https://oauth.authing.cn/oauth/github/redirect)
,而後建立好應用以後,取出 Client ID
和 Client Secret
:
以後就是相似以前的操做,進入 Authing 控制檯,配置 Github 相關的內容:
最後能夠看到以下效果:
至此,本篇教程也就結束了,相信你已經感覺到了 Authing 身份認證機制的強大與便捷。在當今 Serverless 時代,愈來愈多標準化的流程(例如身份驗證、人工智能應用等等)正在逐漸邁向雲端,成爲一種可直接消費的資源,而咱們做爲應用終端的開發者則能夠將更多的時間和精力放在打磨和完善自身的產品上,在必定程度上解放了生產力。
圖雀社區秉承「加速技術傳播」的理念,致力於推廣可以真正讓開發者和用戶的生活變得更美好的技術。
想要學習更多精彩的實戰技術教程?來 圖雀社區逛逛吧。