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

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

时间:2023-11-30 本站 点击:1

前言

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

注册

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

前端部分逻辑

前端其实就两个。

关于这部分的话是前端自己生成了验证码,前端校验账号密码长度是否合法。 关于这部分前端代码见: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

@ControllerpublicclassUserRegist{@AutowiredUserServiceuserService;@AutowiredRegistMessageregistMessage;@ResponseBody@PostMapping("/regist")publicRegistMessageSaveUser(@RequestBodyMap<String,Object>usermap){Stringusername=(String)usermap.get("username");Stringpassword=(String)usermap.get("password");QueryWrapper<User>UsersWrapper=newQueryWrapper<>();UsersWrapper.eq("UserName",username);if(userService.IsExitsUser(UsersWrapper)){registMessage.setFlag(0);returnregistMessage;}else{Useruser=newUser();user.setUserName(username);user.setUserPassword(password);userService.SaveUser(user);registMessage.setFlag(1);returnregistMessage;}}}

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

再然后就是前端重新拿到数据

判断情况。

登录

同样的登录也要进行区分,但是这里面稍微麻烦的是这边我们还要生成一个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.successthis.formLogin.token=res.data.tokenif(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)=>{letobj={data:value,time:Date.now(),expire:expire};localStorage.setItem(key,JSON.stringify(obj));}Storage.prototype.getExpire=key=>{letval=localStorage.getItem(key);if(!val){returnval;}val=JSON.parse(val);if(Date.now()-val.time>val.expire){localStorage.removeItem(key);returnnull;}returnval.data;}

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

localStorage.getExpire("token")

后端处理

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

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

用户登录

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

生成token

这里用到 jwt

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.6.0</version></dependency>

packagecom.huterox.whiteholeboot.utils.TokenProccessor;/***生成token*/importjava.util.Date;importjava.util.HashMap;importjava.util.Map;importcom.huterox.whiteholeboot.Dao.Mapper.UserMapper.UserServer.UserService;importcom.huterox.whiteholeboot.Dao.Pojo.UserPojo.User;importio.jsonwebtoken.*;importorg.springframework.beans.factory.annotation.Autowired;publicclassTokenProccessor{privatestaticUserServiceuserService=newUserService();privatestaticfinallongEXPIRE_TIME=60*60*1000*24*7;//过期时间7天privatestaticfinalStringKEY="huterox";//加密秘钥/***生成token*由于只有当账号密码正确之后才会生成token所以这边只需要用户名进行识别*@paramuserName用户名*@return*/publicstaticStringcreateToken(StringuserName){Map<String,Object>header=newHashMap();header.put("typ","JWT");header.put("alg","HS256");JwtBuilderbuilder=Jwts.builder().setHeader(header).setExpiration(newDate(System.currentTimeMillis()+EXPIRE_TIME)).setSubject(userName)//设置信息,也就是用户名.setIssuedAt(newDate()).signWith(SignatureAlgorithm.HS256,KEY);//加密方式returnbuilder.compact();}/***验证token是否有效*@paramtoken请求头中携带的token*@returntoken验证结果2-token过期;1-token认证通过;0-token认证失败*/publicstaticintverify(Stringtoken){Claimsclaims=null;try{//token过期后,会抛出ExpiredJwtException异常,通过这个来判定token过期,claims=Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();}catch(ExpiredJwtExceptione){return2;}//从token中获取用户名,当用户查询通过后即可Stringusername=claims.getSubject();Useruser=userService.selectUserByName(username);if(user!=null){return1;}else{return0;}}}

拦截器设置

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

packagecom.huterox.whiteholeboot.Config;importcom.alibaba.fastjson.JSON;importcom.huterox.whiteholeboot.utils.TokePassJson.TokenPassJson;importcom.huterox.whiteholeboot.utils.TokenProccessor.TokenProccessor;importorg.springframework.stereotype.Component;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;@ComponentpublicclassTokenInterceptorimplementsHandlerInterceptor{@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{if(request.getMethod().equals("OPTIONS")){response.setStatus(HttpServletResponse.SC_OK);returntrue;}response.setCharacterEncoding("utf-8");Stringtoken=request.getHeader("token");intresult=0;if(token!=null){result=TokenProccessor.verify(token);if(result==1){System.out.println("通过拦截器");returntrue;}}response.setCharacterEncoding("UTF-8");response.setContentType("application/json;charset=utf-8");try{TokenPassJsonjson=newTokenPassJson();json.setSuccess(result);//0表示验证失败,2表示过期response.getWriter().append(JSON.toJSONString(json));System.out.println("认证失败,未通过拦截器");}catch(Exceptione){e.printStackTrace();response.sendError(500);returnfalse;}returnfalse;}}

packagecom.huterox.whiteholeboot.Config;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.concurrent.ConcurrentTaskExecutor;importorg.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.Executors;@ConfigurationpublicclassTokenConfigimplementsWebMvcConfigurer{//@Override//publicvoidaddCorsMappings(CorsRegistryregistry){//registry.addMapping("/**")//.allowCredentials(true)//.allowedHeaders("*")//.allowedMethods("*")//.allowedOrigins("*");////}//跨域,我们前端做了跨域所以的话后端不用,也是为了安全,不能什么阿猫阿狗都过来访问@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){List<String>excludePath=newArrayList<>();//排除拦截,除了注册登录(此时还没token),其他都拦截excludePath.add("/regist");//登录excludePath.add("/login");//注册excludePath.add("/static/**");//静态资源excludePath.add("/assets/**");//静态资源registry.addInterceptor(newTokenInterceptor()).addPathPatterns("/**").excludePathPatterns(excludePath);WebMvcConfigurer.super.addInterceptors(registry);}}

之后就可happy访问了。

总结

进度有点慢,没办法先磨合一些。此为如果觉得本文不错请给个赞赞~


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/SpringBoot/4426.html