SpringBoot+Vue前后端分离实战(用户注册登录)

您所在的位置:网站首页 vscode登录注册代码 SpringBoot+Vue前后端分离实战(用户注册登录)

SpringBoot+Vue前后端分离实战(用户注册登录)

2024-07-12 15:07| 来源: 网络整理| 查看: 265

文章目录 前言注册前端部分逻辑发送请求后端处理 登录前端获取token前端token状态管理后端处理用户登录 生成token拦截器设置 总结

前言

昨天抽空终于把后端架起来了,准备开始编写后端,结果由于是第一次做前后端分离,搞的我闹了不少洋相,查了半天资料发现是个小细节没搞好,气死我。

注册

既然要登录那必然是先少不了注册,注册之后才能去登录呀。 那么咱们这个毕竟是作为一个前后端分离的项目,所以的话注册部分的逻辑也是分两个部分,一个是前端部分,一个是后端部分。 在这里插入图片描述

前端部分逻辑

前端其实就两个。 在这里插入图片描述

关于这部分的话是前端自己生成了验证码,前端校验账号密码长度是否合法。 在这里插入图片描述 关于这部分前端代码见:Vue实战开发(一)验证码与登录页面

发送请求

这个也是比较重要的一部分,我这边使用的是 Axios 发送请求。但是这里一定要注意一个细节 Axios发送的请求参数是封装在requestbody里面的,这个关系到我们后面怎么拿数据,先前我就是不知道这个,搞得我一直接收不到参数 不过在此之前我们必须做一件事前,那就是跨域处理 这一块我是在前端做的,后端没去做,为了保证我后端的安全。 在这里插入图片描述

proxyTable: { '/boot': { target: 'http://localhost:8000/', changeOrigin: true, pathRewrite: { '^/boot': '' } } },

target 是你的服务器,/boot 是指代那个主机。 那么现在我们开始发送请求 在这里插入图片描述

Register(){ this.axios({ url: "/boot/regist", method: 'post', data: { username: this.formRegist.username, password: this.formRegist.password.toLowerCase(), } }).then(res =>{ this.flag = res.data.flag; if(this.flag =='1'){ alert("注册成功") this.$router.push("/login") } else { alert("注册失败用户名已存在!") } })

在这里插入图片描述 在这里插入图片描述

后端处理

这里的话我要说一下那个参数,那个flag就是来说明用户是否注册成功的,如果成功 flag 为1 反之为 0

现在把目光移步到 springboot 这边的逻辑其实很简单,就是检查用户名是否存在,存在就不注册,然后返回flag

@Controller public class UserRegist { @Autowired UserService userService; @Autowired RegistMessage registMessage; @ResponseBody @PostMapping("/regist") public RegistMessage SaveUser(@RequestBody Map usermap){ String username = (String) usermap.get("username"); String password = (String) usermap.get("password"); QueryWrapper UsersWrapper = new QueryWrapper(); UsersWrapper.eq("UserName",username); if(userService.IsExitsUser(UsersWrapper)){ registMessage.setFlag(0); return registMessage; } else { User user = new User(); user.setUserName(username); user.setUserPassword(password); userService.SaveUser(user); registMessage.setFlag(1); return registMessage; } } }

在这里插入图片描述

之后在数据库就能见到注册好的账号密码了。

再然后就是前端重新拿到数据 在这里插入图片描述 判断情况。

登录

同样的登录也要进行区分,但是这里面稍微麻烦的是这边我们还要生成一个token用来记录用户的登录状态,并且由于是前后端分离,所以我们不能直接用session 或者 cookie ,像先前用Django那样直接request.session,或者 springboot 那样直接 Httpsession 。这边我们需要自己去加密token,并且让前端保存token。

这边我们还是先看到前端吧。 前端唯一要做的就是发送用户和密码,然后接收token。以后请求敏感页面的时候就会带入token。

前端获取token

核心的话就只有这个

logincount(){ this.axios({ url: "/boot/login", method: 'post', headers: { "Huterox": "hello" }, data: { username: this.formLogin.username, password: this.formLogin.password.toLowerCase(), } }).then(res =>{ this.formLogin.success = res.data.success this.formLogin.token = res.data.token if(this.formLogin.success =='1'){ //设置token七天过期 localStorage.setExpire("token",this.formLogin.token,1000*60*60*24*7); alert("登录成功~") this.$router.push("/space") } else { alert("用户名或密码错误!") } }) },

那个success和flag是一个东西。

前端token状态管理

由于没有cookie所以我们这边需要自己保存一下token,但是由于vuex 的session在页面关闭或者刷新之后就没了所以只能用 localStorage 但是这玩意的话没有办法设置过期时间所以还要自己动手处理一下。 封装 localStorage的方法。

在这里插入图片描述

Storage.prototype.setExpire=(key, value, expire) =>{ let obj={ data:value, time:Date.now(), expire:expire }; localStorage.setItem(key,JSON.stringify(obj)); } Storage.prototype.getExpire= key =>{ let val =localStorage.getItem(key); if(!val){ return val; } val =JSON.parse(val); if(Date.now()-val.time>val.expire){ localStorage.removeItem(key); return null; } return val.data; }

之后敏感页面自己在判断有木有token就好了。

localStorage.getExpire("token")

后端处理

这一套在前端处理起来是相对容易,那么接下来就是后端了。当然在后端主要是涉及到生成token和校验token。毕竟前端只需要判断有误token即可,后端是要验证的,至于怕不怕有人恶意篡改,只要你改了,我后端验证就过不了,我后面引入Redis就专门记录这种情况,正常情况下token不会被恶意篡改,也就是能够通过校验,一旦过不了那很大概率是被恶意篡改了,那就拉入监控名单,次数超过限制关进小黑屋,或者前端调用浏览器定位。安全这块我本人是比较注重的,比较玩过一段时间的信安。

先回到这里,我们继续说说下面怎么处理。

用户登录

在这里插入图片描述

之后前端查看返回结果。成功了就有token

生成token

这里用到 jwt

io.jsonwebtoken jjwt 0.6.0 package com.huterox.whiteholeboot.utils.TokenProccessor; /** * 生成token */ import java.util.Date; import java.util.HashMap; import java.util.Map; import com.huterox.whiteholeboot.Dao.Mapper.UserMapper.UserServer.UserService; import com.huterox.whiteholeboot.Dao.Pojo.UserPojo.User; import io.jsonwebtoken.*; import org.springframework.beans.factory.annotation.Autowired; public class TokenProccessor { private static UserService userService=new UserService(); private static final long EXPIRE_TIME=60*60*1000*24*7; //过期时间7天 private static final String KEY = "huterox"; //加密秘钥 /** * 生成token * 由于只有当账号密码正确之后才会生成token所以这边只需要用户名进行识别 * @param userName 用户名 * @return */ public static String createToken(String userName){ Map header = new HashMap(); header.put("typ","JWT"); header.put("alg","HS256"); JwtBuilder builder = Jwts.builder().setHeader(header) .setExpiration(new Date(System.currentTimeMillis()+EXPIRE_TIME)) .setSubject(userName)//设置信息,也就是用户名 .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,KEY);//加密方式 return builder.compact(); } /** * 验证token是否有效 * @param token 请求头中携带的token * @return token验证结果 2-token过期;1-token认证通过;0-token认证失败 */ public static int verify(String token){ Claims claims = null; try { //token过期后,会抛出ExpiredJwtException 异常,通过这个来判定token过期, claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody(); }catch (ExpiredJwtException e){ return 2; } //从token中获取用户名,当用户查询通过后即可 String username = claims.getSubject(); User user = userService.selectUserByName(username); if(user != null){ return 1; }else{ return 0; } } } 拦截器设置

这里的话是需要用到拦截器了,主要是后面的处理,登录之后某些请求时需要token的,那么这里就要检验。 在这里插入图片描述

package com.huterox.whiteholeboot.Config; import com.alibaba.fastjson.JSON; import com.huterox.whiteholeboot.utils.TokePassJson.TokenPassJson; import com.huterox.whiteholeboot.utils.TokenProccessor.TokenProccessor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{ if(request.getMethod().equals("OPTIONS")){ response.setStatus(HttpServletResponse.SC_OK); return true; } response.setCharacterEncoding("utf-8"); String token = request.getHeader("token"); int result = 0; if(token != null){ result = TokenProccessor.verify(token); if(result == 1){ System.out.println("通过拦截器"); return true; } } response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); try{ TokenPassJson json = new TokenPassJson(); json.setSuccess(result);//0表示验证失败,2表示过期 response.getWriter().append(JSON.toJSONString(json)); System.out.println("认证失败,未通过拦截器"); }catch (Exception e){ e.printStackTrace(); response.sendError(500); return false; } return false; } } package com.huterox.whiteholeboot.Config; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor; import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; @Configuration public class TokenConfig implements WebMvcConfigurer { // @Override // public void addCorsMappings(CorsRegistry registry) { // registry.addMapping("/**") // .allowCredentials(true) // .allowedHeaders("*") // .allowedMethods("*") // .allowedOrigins("*"); // // } // 跨域,我们前端做了跨域所以的话后端不用,也是为了安全,不能什么阿猫阿狗都过来访问 @Override public void addInterceptors(InterceptorRegistry registry){ List excludePath = new ArrayList(); //排除拦截,除了注册登录(此时还没token),其他都拦截 excludePath.add("/regist"); //登录 excludePath.add("/login"); //注册 excludePath.add("/static/**"); //静态资源 excludePath.add("/assets/**"); //静态资源 registry.addInterceptor(new TokenInterceptor()) .addPathPatterns("/**") .excludePathPatterns(excludePath); WebMvcConfigurer.super.addInterceptors(registry); } }

之后就可happy访问了。

总结

进度有点慢,没办法先磨合一些。此为如果觉得本文不错请给个赞赞~(白嫖可耻,尤其是收藏了还不敢赞赞(下次 收藏数>点赞 ?收费:免费))



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3