昨天抽空终于把后端架起来了,准备开始编写后端,结果由于是第一次做前后端分离,搞的我闹了不少洋相,查了半天资料发现是个小细节没搞好,气死我。
既然要登录那必然是先少不了注册,注册之后才能去登录呀。
那么咱们这个毕竟是作为一个前后端分离的项目,所以的话注册部分的逻辑也是分两个部分,一个是前端部分,一个是后端部分。

前端其实就两个。

关于这部分的话是前端自己生成了验证码,前端校验账号密码长度是否合法。

关于这部分前端代码见:Vue实战开发(一)验证码与登录页面
这个也是比较重要的一部分,我这边使用的是 Axios 发送请求。但是这里一定要注意一个细节
Axios发送的请求参数是封装在requestbody里面的,这个关系到我们后面怎么拿数据,先前我就是不知道这个,搞得我一直接收不到参数
不过在此之前我们必须做一件事前,那就是跨域处理 这一块我是在前端做的,后端没去做,为了保证我后端的安全。

proxyTable: { '/boot': { target: 'http://localhost:8000/', changeOrigin: true, pathRewrite: { '^/boot': '' } } }, 1234567891011'
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("注册失败用户名已存在!") } })
123456789101112131415161718'

这里的话我要说一下那个参数,那个flag就是来说明用户是否注册成功的,如果成功 flag 为1 反之为 0
现在把目光移步到 springboot
这边的逻辑其实很简单,就是检查用户名是否存在,存在就不注册,然后返回flag
@Controller public class UserRegist { @Autowired UserService userService; @Autowired RegistMessage registMessage; @ResponseBody @PostMapping("/regist") public RegistMessage SaveUser(@RequestBody Map<String, Object> usermap){ String username = (String) usermap.get("username"); String password = (String) usermap.get("password"); QueryWrapper<User> 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; } } }
12345678910111213141516171819202122232425262728293031
之后在数据库就能见到注册好的账号密码了。
再然后就是前端重新拿到数据

判断情况。
同样的登录也要进行区分,但是这里面稍微麻烦的是这边我们还要生成一个token用来记录用户的登录状态,并且由于是前后端分离,所以我们不能直接用session 或者 cookie ,像先前用Django那样直接request.session,或者 springboot 那样直接 Httpsession 。这边我们需要自己去加密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("用户名或密码错误!") } }) },
1234567891011121314151617181920212223'那个success和flag是一个东西。
由于没有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; }
1234567891011121314151617181920212223'之后敏感页面自己在判断有木有token就好了。
localStorage.getExpire("token")
这一套在前端处理起来是相对容易,那么接下来就是后端了。当然在后端主要是涉及到生成token和校验token。毕竟前端只需要判断有误token即可,后端是要验证的,至于怕不怕有人恶意篡改,只要你改了,我后端验证就过不了,我后面引入Redis就专门记录这种情况,正常情况下token不会被恶意篡改,也就是能够通过校验,一旦过不了那很大概率是被恶意篡改了,那就拉入监控名单,次数超过限制关进小黑屋,或者前端调用浏览器定位。安全这块我本人是比较注重的,比较玩过一段时间的信安。
先回到这里,我们继续说说下面怎么处理。
用户登录
之后前端查看返回结果。成功了就有token
这里用到 jwt
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.6.0</version> </dependency> 12345
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<String,Object> 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; } } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 拦截器设置这里的话是需要用到拦截器了,主要是后面的处理,登录之后某些请求时需要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; } }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849package 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<String> 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); } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748之后就可happy访问了。
进度有点慢,没办法先磨合一些。此为如果觉得本文不错请给个赞赞~(白嫖可耻,尤其是收藏了还不敢赞赞(下次 收藏数>点赞 ?收费:免费))
相关知识
Springboot+vue的客户关系管理系统(有报告),Javaee项目,springboot vue前后端分离项目
基于SpringBoot+Vue“花开富贵”花园管理系统设计和实现(源码+LW+部署讲解)
基于SpringBoot+Vue的鲜花销售/鲜花商城/花店管理系统
Java实现鲜花预定系统:Oracle数据库与Spring Boot框架整合实战
Java实战项目
基于springboot+vue的花艺烘焙商城系统微信小程序
java基于Springboot+vue的鲜花预定销售商城网站 毕业设计
基于SpringBoot+Vue的花店管理系统的设计与实现(源码+lw+部署+讲解)
计算机毕业设计Springboot+vue的鲜花销售网站(源码+系统+mysql数据库+Lw文档)
基于SpringBoot+Vue的软件产品展示销售系统的设计与实现(源码+lw+部署+讲解)
网址: SpringBoot+Vue前后端分离实战(用户注册登录) https://m.huajiangbk.com/newsview948791.html
| 上一篇: ASP.NET 链接sql数据库 |
下一篇: C语言实现登录注册 |