登陆注册功能是一个网站必不可少的功能,其主要思路也相对很简单,获取用户输入的信息,验证信息,若成功则上传到后台数据库。登陆时获取用户信息,如果和数据库中的用户信息匹配,则登陆成功,并把登陆成功的信息写入cookies和session,使用户在未来几天内登陆可以不用输账号密码。源码会放在文末,源码的开发进度会快于这篇博客。
# (一)分别搭建一个登陆和注册界面 {#一-分别搭建一个登陆和注册界面}
这一步的界面依旧来自于Bootstrap官网,官网的起步处正好有登陆界面,那就直接拿过来修改一下了,login.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>登陆界面</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link href="css/signin.css" rel="stylesheet">
</head>
<body>
<div class="container">
<form class="form-signin" action="/logincheck" method="post">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="username" class="sr-only">Username</label>
<input type="username" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<span><a href="/register" style=" font-size: 12px;float: right;margin-top: 7px;">重新注册一个用户</a></span>
</form>
</div> <!-- /container -->
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
写个css来美化一下页面的布局signin.css
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="username"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.register{
font-size: 12px;
float: right;
margin-top: 7px;
}
这样一个登陆界面就完成了,注册页面和登陆界面基本一样,只需要复制过去稍作修改就行。前端的内容毕竟不是我们的主要内容,对后端SpringBoot的深入理解才是我们真正要做的事情。
# (二)登陆与注册的后端处理逻辑 {#二-登陆与注册的后端处理逻辑}
对于目前的数据库表,还是以最简单的表结构为主,后期需要增加新内容时继续修改就行
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`token` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
)
目前只包含四个属性,用户id控制用户唯一性,用户名和密码不用多讲,token是接下来写cookie时会用到的一个属性,主要保存cookie的一个值。对数据库的增删改查全部写在mapper包下,新建一个UserMapper,通过注解的形式实现增删改查。
@Mapper
public interface UserMapper {
@Insert("insert into user(name,password,token) values (#{name},#{password},#{token})")
void insert(User user);
@Select("select * from user where name=#{name} and password=#{password}")
User select(User user);
@Select("select * from user where token=#{token}")
User findBytoken(String token);
@Select("select * from user where id=#{createid}")
User findById(int createid);
}
先写注册的controller,@GetMapping处理get请求,@PostMapping处理Post请求,在注册时会随机生成一个token,如果注册成功直接跳转到首页,并写入cookies
@Controller
public class registerController {
@Resource
private UserMapper userMapper;
@GetMapping("/register")
public String register(){
return "register";
}
@PostMapping("/registercheck")
public String registercheck(HttpServletRequest request,HttpServletResponse response){
String username=request.getParameter("username");
String password=request.getParameter("password");
//随机生成一个token用来当cookies的value
String token= UUID.randomUUID().toString();
User user=new User();
user.setName(username);
user.setPassword(password);
user.setToken(token);
userMapper.insert(user);
//如果用户注册成功,则把用户信息写进session,直接跳转到主页
if(userMapper.select(user)!=null){
response.addCookie(new Cookie("token",token));
return "redirect:/index";
}else {
//注册失败,处理方法先省略
return "register";
}
}
}
loginController的实现方式也和注册类似,通过查询数据库确定用户是否存在,如果存在则写入cookies并跳转到index首页。登陆失败后的处理流程目前还未写。
@Controller
public class logincontroller {
@Resource
private UserMapper userMapper;
@GetMapping("/login")
public String login(){
return "login";
}
@PostMapping("/logincheck")
public String checklogin(HttpServletRequest request, HttpServletResponse response){
//通过request获取输入的用户名和密码在数据库中查找相关用户,如果存在就登陆成功
User user=new User();
String name=request.getParameter("username");
String password=request.getParameter("password");
user.setName(name);
user.setPassword(password);
User newUser=userMapper.select(user);
if(newUser != null){
String token=newUser.getToken();
response.addCookie(new Cookie("token",token));
}else{
//登陆失败,重新登陆
}
return "redirect:/index";
}
}
跳转到index主页后indexController需要去处理cookies信息,把用户信息写进session中方便html的调用:
@Controller
public class indexController {
@GetMapping("/index")
public String index(HttpServletRequest request,Model model){
//查找cookies,观察是否有token存在
Cookie[] cookies=request.getCookies();
if(cookies==null){
return "login";
}
User user=null;
for (Cookie cookie:cookies){
if(cookie.getName().equals("token")){
String token=cookie.getValue();
user=userMapper.findBytoken(token);
if(user!=null){
request.getSession().setAttribute("user",user);
}
break;
}
}
return "index";
}
}
最后在index.html文件中做个小小的改动,我希望当检测到用户登陆时,在顶端的导航栏右侧显示用户个人名,如果用户未登录,则显示登陆按钮,我们使用Thymeleaf框架实现数据传送。
<li th:if="${session.user == null}"><a href="/login">登陆</a></li>
<li class="dropdown" th:if="${session.user} != null">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" th:text="${session.user.getName()}"><span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">消息中心</a></li>
<li><a href="#">个人资料</a></li>
<li><a href="#">退出登陆</a></li>
</ul>
</li>
通过th:if语句来识别用户是否已经登陆,如果已经登陆,就显示用户名,如果未登陆,则显示登陆。最后附上源代码:
https://github.com/OliverLiy/MyBlog