在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.