不像先有鸡还是先有蛋这种话题,对于系统来说必须要先注册再登录,所以这一章主要就是讲注册,对于注册来说首先就是要有一个注册的页面,从系统的安全角度去考虑,这个注册页面可以是系统自带的注册页面,也可以是符合系统注册接口要求的分离页面。

Spring Security使用总结三,编写一个注册页面,不知道你有没有强迫症-LMLPHP

本着多学习一点知识的角度,我就整了一个系统自带的注册页面,也就是整了一个页面模板,所以就需要多依赖下面的这几个项目:一个是模板项目thymeleaf,一个是可以少写get,set方法的lombok,这里都是简单使用,不会喧宾夺主。

<!--页面模板-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>2.7.4</version>
</dependency>

<!--Lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
</dependency>

因为是注册页面,肯定要多出一个注册服务,所以需要新建一个RegisterController,代码如下:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class RegisterController {

    @RequestMapping("/register")
    public String register(){
        return "register";
    }
}

注意看,这里面就是用的Controller注解,而不是RestController注解,因为这里面就用到了模板,返回的就是页面的名字,既然有了页面的名字,没有页面也找不到,所以会有一个页面代码,我将这个页面代码放到了resources文件夹中的templates文件夹下,resources文件夹不用过多介绍,这个templates文件夹是我自己创建的:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">

    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <title>注册</title>
    </head>

    <body>

        <div class="container">
            <div class="row">
                    <h1>注册</h1>
                    <form id="userinfo" >

                        <div class="form-group" >
                            <label for="name" class="control-label">用户名</label>
                            <input id="name" class="form-control"  />
                        </div>
                        <div class="form-group" >
                            <label for="password" class="control-label">密码</label>
                            <input id="password" class="form-control" type="password"  />
                        </div>
                        <div class="form-group" >
                            <label for="confirmPassword" class="control-label">密码确认</label>
                            <input id="confirmPassword" class="form-control" type="password"  />
                        </div>
                        <div class="form-group">
                            <button id="register" type="submit" class="btn btn-success">注册</button>
                        </div>
                    </form>
            </div>
        </div>

    </body>
</html>

有了Controller提供访问页面的途径,也有了页面资源,这个时候就需要让模板知道,这个页面资源放在那里,所以就需要在配置文件application.properties里面添加如下配置:

#thymeleaf--------------------------------
spring.thymeleaf.cache=true
spring.thymeleaf.checktemplate=true
spring.thymeleaf.check-template-location=true
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.suffix=.html
spring.thymeleaf.prefix=classpath:templates/

好了,可以启动一下,看看能不能访问到这个页面,当然访问不了,当你输入http://localhost:8080/register之后你会发现,和访问http://localhost:8080/hello是一样的,什么都没有,这个时候就需要security的配置了,在配置类里面添加点内容,如下所示,添加什么了自己发现。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
            //关闭csrf
            .csrf().disable()
            //不通过Session获取SecurityContext
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            //permitAll表示所有人都能访问
            .antMatchers(new String[]{"/register"}).permitAll()
            .antMatchers(matchers).anonymous()
            // 除上面外的所有请求全部需要鉴权认证
            .anyRequest().authenticated()
            .and()
            //允许加载静态资源
            .headers().frameOptions().sameOrigin();
}

启动后再次访问http://localhost:8080/register ,就会出现下面这个页面,成功完成注册页面的开发:

Spring Security使用总结三,编写一个注册页面,不知道你有没有强迫症-LMLPHP

附加

因为我有强迫症,我看着这个页面我就很难受(其实一点不难受),所以我就必须要多添加一些东西,让这个页面看上去至少不这么丑。于是我就在页面代码中引入了一些Bootstrap的样式,在注册的HTML中加入下面几行代码:

<link rel="stylesheet" type="text/css" th:href="@{/static/css/bootstrap.min.css}"/>
<script type="text/javascript" th:src="@{/static/js/jquery-3.2.1.min.js}"></script>
<script type="text/javascript" th:src="@{/static/js/bootstrap.min.js}"></script>

你再访问http://localhost:8080/register ,你发现,什么玩意嘛,完全没有生效啊,为什么没有生效?这个没有生效的罪魁祸首依旧是security,这个security就是这么的缜密,只要你访问资源,你没有配置这个资源,那这个资源就需要认证授权后才能访问,所以这里就需要配置一下,和Controller里面的服务不同的是,这些是页面的静态资源,需要在SecurityConfig类中添加一个方法:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter

    //这里是省略的代码
    //... ...
 
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/static/**");
    }
}

新建一个类,代码如下所示:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /**
     * 配置静态资源
     * @param registry 资源处理方法注册
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }
}

重启项目,再次访问http://localhost:8080/register ,变成了如下模样:

Spring Security使用总结三,编写一个注册页面,不知道你有没有强迫症-LMLPHP

现在的文件结构和上一节的对比如下所示:

Spring Security使用总结三,编写一个注册页面,不知道你有没有强迫症-LMLPHP

多了一个security的配置,多了一个注册用的controller,多了前台注册页面相关的静态资源,配置文件里面多了模板的相关配置,pom里面多了一些依赖

11-06 11:19