赞
踩
后端:javaWeb(SpringMvc+mybatis)
数据库:Mysql
使用vue-element-admin封装好的登陆接口,与自己后端的接口相匹配,完成登陆页面的跳转。
对于正常登陆来说,vue-element-admin对每一个页面请求都设置有拦截器,封装有token的方法,每次在发送请求时,都会找寻浏览器中的Cookice是否存有token值,如果有则每次发送请求时,携带token,与后端交互。如果没有,vue-element-admin会直接跳到首页,重新登陆。
后端通过设置拦截器获取token,用token值,再转义成明文用户名或密码(之前设置token用什么映射数据库实体类的对象名保持一致),之后经过数据库查询是否有此对象,有则,正常请求,没有则代表token失效、错误等代表此次请求不允许,vue-element-admin接收到后端的token失败反馈后,跳转到登陆页面。
后端简述:共计两个对外的接口,
①、通过前端接受的账号和密码查询数据库验证账号和密码是否正确,正确则使用jwt将用户名和密码转移为token,之后返回给前端指定数据。
②、页面跳转请求时先单独携带token令牌发送给后端,进行验证,是否是登陆状态,是再允许之后的请求,不是则返回规定的数据格式。
JWT依赖、JSON依赖:
JWT:生成token的一种方式
JSON:前后端传输数据的格式
- //jwt依赖
- <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>4.4.0</version>
- </dependency>
- //由于我使用的后端接受格式是JSON,所以又需要的JSON依赖
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>${jackson_version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>${jackson_version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>${jackson_version}</version>
- </dependency>
如果只是想使用简单的编写接口就实现登陆页面的功能,那么返回前端规定的接受数据格式,后端
返回指定的数据格式就可以了。具体代码如下:
- loginDto loginDto = new loginDto();
- loginDto.setName(user.getUserName());//姓名
- loginDto.setAvatar(user.getAvatar());//头像
- loginDto.setIntroduction("个性签名");//签名
- List<String> roles = new ArrayList();//注意此属性前端规定,必须是数组结构。
- roles.add("admin");//角色
- loginDto.setRoles(roles);
- return new Result(20000, "登录成功", loginDto);
目录:/src/api/index.js
需要更改处:账号名:userEmail 密码:password
- <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
-
- <div class="title-container">
- <h3 class="title">
- WMS 登陆
- </h3>
- <lang-select class="set-language" />
- </div>
-
- <el-form-item prop="userEmail">
- <span class="svg-container">
- <svg-icon icon-class="user" />
- </span>
- <el-input
- ref="userEmail"
- v-model="loginForm.userEmail"
- placeholder="请输入用户名……"
- name="userEmail"
- type="text"
- tabindex="1"
- autocomplete="on"
- />
- </el-form-item>
-
- <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
- <el-form-item prop="password">
- <span class="svg-container">
- <svg-icon icon-class="password" />
- </span>
- <el-input
- :key="passwordType"
- ref="password"
- v-model="loginForm.password"
- :type="passwordType"
- placeholder="请输入密码……"
- name="password"
- tabindex="2"
- autocomplete="on"
- @keyup.native="checkCapslock"
- @blur="capsTooltip = false"
- @keyup.enter.native="handleLogin"
- />
- <span class="show-pwd" @click="showPwd">
- <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
- </span>
- </el-form-item>
- </el-tooltip>
-
- <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">
- 登陆
- </el-button>
- </el-form>
目录:src/api/user.js
- import request from '@/utils/request'
-
- export function login(data) {
- return request({
- url: 'http://xxx/login',//后端登陆接口
- method: 'get',//请求方式
- //请求参数--JSON格式,对应的是登录时,填入的账号和密码数据
- params: {
- userEmail: data.userEmail,
- password: data.password
- }
- })
- }
-
- export function getInfo(token) {
- return request({
- url: 'http://xxx/getLogin',//携带token的请求,判断登陆状态
- method: 'get',//请求方式
- params: { token }//请求参数--JSON格式(读取的是浏览器的Cookice保存的值'token'名字不需要修改)
- })
- }
-
- export function logout() {
- return request({
- url: '/vue-element-admin/user/logout',
- method: 'post'
- })
- }
根目录下:/permission.js 相当于拦截器 代码不需要修改
- router.beforeEach(async(to, from, next) => {
- // start progress bar
- NProgress.start()
-
- // set page title
- document.title = getPageTitle(to.meta.title)
-
- // determine whether the user has logged in
- const hasToken = getToken()
- //能在Cookice中读取出token值运行下面代码
- if (hasToken) {
- if (to.path === '/login') {
- // if is logged in, redirect to the home page
- next({ path: '/' })
- NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
- } else {
- // determine whether the user has obtained his permission roles through getInfo
- const hasRoles = store.getters.roles && store.getters.roles.length > 0
- if (hasRoles) {
- next()
- } else {
- try {
- // get user info
- // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
- //调用请求,将token发送给后端,判断该用户的登陆状态。
- const { roles } = await store.dispatch('user/getInfo')
-
- // generate accessible routes map based on roles
- const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
-
- // dynamically add accessible routes
- router.addRoutes(accessRoutes)
-
- // hack method to ensure that addRoutes is complete
- // set the replace: true, so the navigation will not leave a history record
- next({ ...to, replace: true })
- } catch (error) {
- //通过接收值判断roles返回值是否为数组,且返回值也相当于一个权限符,在路由中对应页面中能操作的左侧状态栏
- // remove token and go to login page to re-login
- await store.dispatch('user/resetToken')
- Message.error(error || 'Has Error')
- next(`/login?redirect=${to.path}`)
- NProgress.done()
- }
- }
- }
- } else {//读取不到token值,默认没有登陆过,直接跳转到首页,开始进行登陆。
- //白名单,为了将登录页进行排除。如果不设置白名单,则会出现,在登陆请求之前,先通过token获取登陆状态,肯定是没有进行登陆的,那么就不会进行之后登陆请求,会直接跳转到登陆页面再次进行登陆,陷入死循环。
- /* has no token*/
- if (whiteList.indexOf(to.path) !== -1) {
- // in the free login whitelist, go directly
- next()
- } else {
- // other pages that do not have permission to access are redirected to the login page.
- next(`/login?redirect=${to.path}`)
- NProgress.done()
- }
- }
- })
目录:src/stotre/modules/user.js 不需要修改
- // get user info--这是前端每次携带token的请求
- getInfo({ commit, state }) {
- return new Promise((resolve, reject) => {
- getInfo(state.token).then(response => {
- const { data } = response
- if (!data) {
- reject('Verification failed, please Login again.')
- }
- //前端规定的固定数据数据(roles, name, avatar, introduction)
- const { roles, name, avatar, introduction } = data
-
- // roles must be a non-empty array
- if (!roles || roles.length <= 0) {
- reject('getInfo: roles must be a non-null array!')
- }
- commit('SET_ROLES', roles)
- commit('SET_NAME', name)
- commit('SET_AVATAR', avatar)
- commit('SET_INTRODUCTION', introduction)
- resolve(data)
- }).catch(error => {
- reject(error)
- })
- })
- },
1、修改user.jsp中的两个请求地址、发送参数、发送方式。
2、修改index.jsp中的参数名,也可以不对应,只有后端将两个不同的参数名绑定在一起也可以实现。(后端入参可以使用@Param("前端发送参数名" ) 数据类型 后端参数名 对应)
需求根据个人需求,添加相关代码,
接口方法代码片段如下:
- @RequestMapping(value = "/login")
- public Result login(String userEmail, String password) {
- System.out.println("有登陆请求过来……");
- System.out.println("userEmail:" + userEmail);
- System.out.println("password:" + password);
- Map<String, Object> map = new HashMap<>();
- User admin = userService.getAdmin(userEmail, password);
- System.out.println("数据库查询结果:" + admin);
- if (admin == null) {
- map.put("code", 30000);
- map.put("msg", "登陆失败");
- return new Result(30000, "登陆失败");
- } else {
- String token = JwtUtils.sign(userEmail, password);
- //map.put("userEmail", userEmail);
- map.put("token", token);
-
- Result result = new Result();
- result.setCode(20000);
- result.setMsg("登陆成功");
- result.setData(map);
- System.out.println(result);
- return result;
- }
- }
- //请求查询登陆状态
- @RequestMapping(value = "/getLogin")
- public Result getLogin(HttpServletRequest request) {
- String token = request.getParameter("token");
- System.out.println("--->>>>" + token);
- if (token == null || token.equals("")) {
- Result result = new Result();
- result.setCode(40000);
- result.setMsg("登陆失败,token失效");
- System.out.println(result);
- return result;
- } else {
- String userEmail = JwtUtils.getClaim(token, "iss");
- User user = userMapper.getUserByEmail(userEmail);
- System.out.println(user);
- if (user == null) {
- Result result = new Result();
- result.setCode(50000);
- result.setMsg("登陆失败,token错误");
- System.out.println(result);
- return result;
- } else {
- loginDto loginDto = new loginDto();
- loginDto.setName(user.getUserName());//姓名
- loginDto.setAvatar(user.getAvatar());//头像
- loginDto.setIntroduction("个性签名");//签名
- List<String> roles = new ArrayList();
- roles.add("admin");//角色
- loginDto.setRoles(roles);
- return new Result(20000, "登录成功", loginDto);
- }
- }
java后端代码片段如下:
- //生成token(数据加密又叫做签名sign)
- public static String sign(String userEmail, String password) {
- //创建算法实例
- Algorithm algorithm = Algorithm.HMAC256(password);
- //System.out.println("token生成前……");
- try {
- String token = JWT.create()
- .withIssuer(userEmail)//设置自定义参数(负载)
- .sign(algorithm);//头
- //System.out.println("token生成后……");
- System.out.println("token:" + token);
- return token;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- //获取token中负载部分的值
- public static String getClaim(String token, String key) {
- DecodedJWT jwt = JWT.decode(token);
- return jwt.getClaim(key).asString();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。