在boke后台登录系统中实现了自动登录的功能,这也是前后端分离的开发模式中最常见的一个问题,如何保持登录状态的持久化。今天就来通过实现自动登录来一步步理清前端数据持久化的思路。
一 实现思路
当用户首次登录时,输入用户名和密码,服务器先校验用户名和密码,如果正确,则根据一定的规则生成一个token并返回给前端,前端将这个token存到locationStorage中,等下次登录时或者进行其他请求时,可以将token传到后台服务器,服务器后先验证token是否有效,有效则进行下一步请求,无效则返回token无效的消息给前端,前端判断之后决定跳转页面。
二 使用的框架和技术
前端使用的是angular4,后台使用JWT来生成token和验证token。
三 代码
@RequestMapping("/login") @ResponseBody public Object login(@RequestBody User user) { Result result = null; Map<String, Object> data = new HashMap<String, Object>(); try { if(loginService.login(user.getUsername(), user.getPassword())) { String token = JWT.createJWT(user.getUsername(), user.getPassword(), 24*60*60*1000); data.put("token", token); result= new Result(SysConstant.STATE_SUCCESS,"login success",data); }else { result= new Result(SysConstant.STATE_FAILURE,"login failure",false); } } catch (Exception e) { result= new Result(SysConstant.STATE_FAILURE,"login failure",false); e.printStackTrace(); } return JSONUtil.toJSON(result); } @RequestMapping("/autoLogin") @ResponseBody public Object autoLogin(@RequestParam("token") String token) { Result result = null; try { CheckResult cr = JWT.validateJWT(token); if(cr.isSuccess()) { result= new Result(SysConstant.STATE_SUCCESS,"auto login success",true); } else { result= new Result(SysConstant.STATE_FAILURE,"auto login failure",false); } } catch (Exception e) { result= new Result(SysConstant.STATE_FAILURE,"auto login failure",false); e.printStackTrace(); } return JSONUtil.toJSON(result); }
下面是前端的代码:
@Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { constructor(private route: Router, private loginService: LoginService, private articleService: ArticleService) { } ngOnInit() { this.loginService.autoLogin().then(response=>{ if(response.code === 0){ this.route.navigate(['/home']); } }) } formSubmit(value) { this.loginService.doLogin(value).then(data=>{ if(data.code === 0){ localStorage.setItem("token",data.data.token); this.route.navigate(['/home']); }else{ console.log("登录失败"); } }); } }
@Injectable() export class LoginService { constructor(private http: HttpClient, private router: Router) { } doLogin(value) :Promise<any> { const body = { username: value.username, password: value.password }; return this.http.post(`/blog/manager/login`, body) .toPromise() .then(res => res); } autoLogin(): Promise<any> { const headers = new HttpHeaders(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); const param = new HttpParams().set("token",localStorage.getItem("token")); return this.http.post(`/blog/manager/autoLogin`, param,{ headers:headers }) .toPromise() .then(res => res); } }
在login组件初始化的时候先去自动登录验证token,如果token验证通过直接进入home页面,如果是第一次登录或者token过期,那么还是在login页面。
四 总结
上面需要注意的几个点:
在java中使用jwt时使用的是jjwt,需要引入jar包。你可以在这里下载 jjwt.jar
上面的代码不全,不能直接粘贴复制,只是提供了实现的关键代码。
That's all for today.