当当当当,我的项目源码已经托管在我的github上了,大家有需要可以去下载查看。
上一篇文章我们已经通过github的API授权接口获取到用户信息,那么这篇文章将对登录做以下优化:
- 点击登录连接,跳转到登录页面,选择github授权方式进行登录
- 授权成功后我们我们跳转到index界面,此时界面登录链接隐藏,显示当前用户名及其他操作
- 我们需将github用户信息进行重新封装,并将token写到cookie中和持久化到数据库,然后每次刷新主页时检查该用户的token信息进行验证,保持页面处于持久化登录状态,直到cookie过期等。
1.优化登录界面
1.1 点击登录跳转至登录授权页面
编写一个登录界面login.html,目前只实现github授权登录,后续实现用户注册登录。
index.html页面优化,将登录链接href改为==/login==
<a href="/login">登录</a>
更改路径后,我们需编写一个路由,如LoginController.java
LoginController.java
@Controller
public class LoginController {
@GetMapping("/login")
public String toLoginPage(){
return "login";
}
}
login.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<!-- 踩过的坑,springboot引入静态资源路径不要加/static/,否则会报404-->
<title>登录</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="/bootstrap-3.3.7/css/bootstrap.min.css">
<!-- github小图标 -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_1643567_vuk2epwoyqo.css">
<!-- login页面样式 -->
<link rel="stylesheet" href="/css/login.css">
<link rel="stylesheet" href="/bootstrap-3.3.7/css/bootstrap-theme.min.css">
<script src="/jquery-1.12.4/jquery-1.12.4.min.js"></script>
<script src="/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="panel panel-login">
<div class="login-form">
</div>
<div class="login-other">
<h5>第三方账号登录</h5>
<a href="https://github.com/login/oauth/authorize?client_id=b5bf62ea34e5a9ba7cf5&redirect_uri=http://localhost:8080/callback&scope=user&state=1" class="btn btn-primary btn-block btn-github" role="button">
<i class="iconfont icon-GitHub"> </i>
GitHub 登录
</a>
</div>
</div>
</body>
</html>
当用户点击GitHub登录链接按钮,就会去github获取授权信息。
为了使登录持久化,我们需要封装一个User对象,并且创建对应的数据库表,将其存储,然后通过token令牌来确认当前用户信息
我们先得添加数据库依赖以及mybatis依赖
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
添加数据库连接信息
applicationContext.properties
spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
User.java
public class User {
private Long id;
private String name;
//第三方登录id
private Long accountId;
//验证token
private String token;
private Long createTime;
private Long modifiedTime;
//省略getter和setter方法
}
UserMapper.java
@Mapper
public interface UserMapper {
@Select("select * from user where account_id = #{accountId}")
User selectUserByAccountId(@Param("accountId") Long accountId);
@Insert("insert into user (account_id,name,token,create_time,modified_time) values (#{accountId},#{" +
"name},#{token},#{createTime},#{modifiedTime})")
void addUser(User user);
@Update("update user set token = #{token},name = #{name},modified_time = #{modifiedTime} where id = #{id}")
void updateUser(User user);
@Select("select * from user where token = #{token}")
User selectUserByToken(@Param("token") String token);
}
对AuthorizationController.java文件进行改造,如下:
@Controller
public class AuthorizationController {
@Autowired
GitHubProvider gitHubProvider;
@Autowired
UserMapper userMapper;
@GetMapping("/callback")
public String callback(@RequestParam(name = "code") String code,
@RequestParam(name = "state") String state,
HttpServletResponse response){
AccessTokenParam accessTokenParam = new AccessTokenParam();
accessTokenParam.setCode(code);
accessTokenParam.setState(state);
accessTokenParam.setClient_id("b5bf62ea34e5a9ba7cf5");
accessTokenParam.setClient_secret("0b08019a841e39355d6fe070209e7f60ac2bce18");
accessTokenParam.setRedirect_uri("http://localhost:8080/callback");
String Token = gitHubProvider.getAccessToken(accessTokenParam); //获取到access_token
String accessToken = Token.split("&")[0].split("=")[1];
//使用access_token获取用户信息
GitHubUser gitHubUser = gitHubProvider.getGitHubUser(accessToken);
if(gitHubUser!=null){
String token = UUID.randomUUID().toString();
//根据accountid查询是否存在该用户
User selectUser = userMapper.selectUserByAccountId(gitHubUser.getId());
//如果存在更新token,用户名及修改时间
if(selectUser!=null){
selectUser.setToken(token);
if(gitHubUser.getName()!=null&&selectUser.getName()!=null&&!gitHubUser.getName().equals(selectUser.getName())){
selectUser.setName(gitHubUser.getName());
}
selectUser.setModifiedTime(System.currentTimeMillis());
userMapper.updateUser(selectUser);
}else{
//如果不存在添加新的用户信息
User user = new User();
user.setName(gitHubUser.getName());
user.setAccountId(gitHubUser.getId());
user.setToken(token);
user.setCreateTime(System.currentTimeMillis());
user.setModifiedTime(user.getCreateTime());
userMapper.addUser(user);
}
response.addCookie(new Cookie("token",token));
}
System.out.println(gitHubUser.getName());
return "redirect:/";
}
}
IndexController.java
@Controller
public class IndexController {
@Autowired
UserMapper userMapper;
@GetMapping("/")
public String index(HttpServletRequest request){
//在访问主页时获取cookies中的token,查询数据库中的用户信息token,如果存在就把该用户设置到session中
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0){
for (Cookie cookie:cookies){
if("token".equals(cookie.getName())){
String token = cookie.getValue();
User user = userMapper.selectUserByToken(token);
if(user!=null){
request.getSession().setAttribute("user",user);
}
}
}
}
return "index";
}
}
LoginController.java //用于登录和登出操作
@Controller
public class LoginController {
@GetMapping("/login")
public String toLoginPage(){
return "login";
}
@GetMapping("/logout")
public String Logout(HttpServletRequest request, HttpServletResponse response){
request.getSession().removeAttribute("user");
Cookie cookie = new Cookie("token",null);
response.addCookie(cookie);
return "redirect:/";
}
}
演示操作如下:
未完待续…