1. 整体框架
1. 前端页面授权 当我们登录网站的时候,如果没有登录,强制让用户重定向到 登录界面
在 router
目录下的 index.js
文件下实现。 router
-> index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 import store from '../store/index' const routes = [ { path : "/" , name : "home" , redirect : "/pk/" , meta : { requestAuth : true , } }, { path : "/pk/" , name : "pk_index" , component : PkIndexView , meta : { requestAuth : true , } }, { path : "/record/" , name : "record_index" , component : RecordIndexView , meta : { requestAuth : true , } }, { path : "/ranklist/" , name : "ranklist_index" , component : RanklistIndexView , meta : { requestAuth : true , } }, { path : "/user/bot/" , name : "user_bot_index" , component : UserBotIndexView , meta : { requestAuth : true , } }, { path : "/user/account/login" , name : "user_account_login" , component : UserAccountLoginView , meta : { requestAuth : false , } }, { path : "/user/account/register" , name : "user_account_register" , component : UserAccountRegisterView , meta : { requestAuth : false , } }, { path : "/404/" , name : "404" , component : NotFound , meta : { requestAuth : false , } }, { path : "/:catchAll(.*)" , redirect : "/404/" , } ] router.beforeEach ((to, from , next ) => { if (to.meta .requestAuth && !store.state .user .is_login ) { next ({name : "user_account_login" }); } else { next (); } })
最终实现效果:如果处于未登录状态,点击 除注册之外的按钮 页面会跳转到 登录界面 。
2. 实现注册页面 在 view
-> user
-> account
下的 UserAccountRegisterView.vue
文件实现,实现方式类似于同目录下的 UserAccountLoginView.vue
可以直接把登录页面的样式复制过来再做修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 <template> <ContentField> <div class="row justify-content-md-center"> <div class="col-3"> <form @submit.prevent="register"> <div class="mb-3"> <label for="username" class="form-label">用户名</label> <input v-model="username" type="text" class="form-control" id="username" placeholder="请输入用户名"> </div> <div class="mb-3"> <label for="password" class="form-label">密码</label> <input v-model="password" type="password" class="form-control" id="password" placeholder="请输入密码"> </div> <div class="mb-3"> <label for="confirmedpassword" class="form-label">密码</label> <input v-model="confirmedpassword" type="password" class="form-control" id="confirmedpassword" placeholder="请再次输入密码"> </div> <div class="error-message">{{ error_message }}</div> <button type="submit" class="btn btn-primary">提交</button> </form> </div> </div> </ContentField> </template> <script> import ContentField from '../../../components/ContentField.vue' import { ref } from 'vue' import router from '../../../router/index' import $ from 'jquery' export default { components: { ContentField }, setup() { let username = ref(''); let password = ref(''); let confirmedPassword = ref(''); let error_message = ref(''); const register = () => { $.ajax({ url: "http://127.0.0.1:8080/user/account/register/", type: "post", data: { username: username.value, password: password.value, confirmedPassword: confirmedPassword.value, }, success(resp) { // 成功直接返回登录界面 if (resp.error_message === "success") { router.push({name: "user_account_login"}); } else { error_message.value = resp.error_message; } }, }); } return { username, password, confirmedPassword, error_message, register, } } } </script> <style scoped> button { width: 100%; } div.error-message { color: red; justify-content: center; } </style>
实现效果图:
在测试的时候可以会遇到不输入密码也可以注册成功的 bug
, 在 RegisterServiceImpl.java
下 修改一下就可以了。
3. 实现登录状态的持久化 当我们的用户重定向到登陆页面的时候,我们需要把用户的 token
存储到浏览器的 local storage
,这样就可以实现登录状态持久化。
首先 修改 store
目录下的 -> user.js
文件,在合适的位置添加下列两行。
1 2 3 localStorage .setItem ("jwt_token" , resp.token );localStorage .removeItem ("jwt_token" );
其次 修改 view
-> user
-> account
下的 UserAccountLoginView.vue
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <script> import ContentField from '../../../components/ContentField.vue' import { useStore } from 'vuex' import { ref } from 'vue' import router from '../../../router/index' export default { components: { ContentField }, setup() { const store = useStore(); let username = ref(''); let password = ref(''); let error_message = ref(''); const jwt_token = localStorage.getItem("jwt_token"); if (jwt_token) { store.commit("updateToken", jwt_token); store.dispatch("getinfo", { success() { router.push({ name: "home" }); }, error() { } }) }else { } const login = () => { error_message.value = ""; store.dispatch("login", { username: username.value, password: password.value, success() { store.dispatch("getinfo", { success() { router.push({ name: 'home' }); console.log(store.state.user); } }) }, error() { error_message.value = "用户名或密码错误"; } }) } return { username, password, error_message, login, } } } </script>
优化前端 在实现前端登录状态持久化之后,刷新页面可能会存在明显的转换,所以下面对前端页面进行优化。
首先 在 store
目录下的 user.js
中添加全局变量和下拉函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 state : { id : "" , username : "" , password : "" , photo : "" , token : "" , is_login : false , pulling_info : true , }, mutations : { updateUser (state, user ) { state.id = user.id ; state.username = user.username ; state.photo = user.photo ; state.is_login = user.is_login ; }, updateToken (state, token ) { state.token = token; }, logout (state ) { state.id = "" ; state.username = "" ; state.photo = "" ; state.token = "" ; state.is_login = false ; }, updatePullingInfo (state, pulling_info ) { state.pulling_info = pulling_info; } },
其次 修改 UserAccountLoginView.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <template> <ContentField v-if ="!$store.state.user.pulling_info" > <div class ="row justify-content-md-center" > <div class ="col-3" > <form @submit.prevent ="login" > <div class ="mb-3" > <label for ="username" class ="form-label" > 用户名</label > <input v-model ="username" type ="text" class ="form-control" id ="username" placeholder ="请输入用户名" > </div > <div class ="mb-3" > <label for ="password" class ="form-label" > 密码</label > <input v-model ="password" type ="password" class ="form-control" id ="password" placeholder ="请输入密码" > </div > <div class ="error-message" > {{ error_message }}</div > <button type ="submit" class ="btn btn-primary" > 提交</button > </form > </div > </div > </ContentField > </template > <script > setup ( ) { const store = useStore (); let username = ref ('' ); let password = ref ('' ); let error_message = ref ('' ); const jwt_token = localStorage .getItem ("jwt_token" ); if (jwt_token) { store.commit ("updateToken" , jwt_token); store.dispatch ("getinfo" , { success ( ) { router.push ({ name : "home" }); store.commit ("updatePullingInfo" , false ); }, error ( ) { store.commit ("updatePullingInfo" , false ); } }) }else { store.commit ("updatePullingInfo" , false ); } } </script >
最后还需要修改 NavBar.vue
。
1 2 3 4 5 6 7 8 9 10 11 12 <ul class ="navbar-nav" v-else -if ="!$store.state.user.pulling_info" > <li class ="nav-item" > <router-link class ="nav-link" :to ="{name: 'user_account_login' }" role ="button" > 登录 </router-link > </li > <li class ="nav-item" > <router-link class ="nav-link" :to ="{name: 'user_account_register'}" role ="button" > 注册 </router-link > </li > </ul>