SpringBoot+Mybatis+PostMan(五):token登陸認證過程一(token生成與認證)


Springboot+Mybatis+redis+postman項目實戰總目錄*

SpringBoot+Mybatis+PostMan(五):token登陸認證過程二(redis緩存引入)

SpringBoot+Mybatis+PostMan(六):token登陸認證過程三(redis封裝與干掉原來session,避免用戶重復登陸)

番外篇:SpringBoot 用戶注冊時經MD5加密存入數據庫

 

第二篇章:用戶角色權限訪問控制

SpringBoot+Mybatis+PostMan(七):用戶角色權限訪問控制入門(數據模擬實現,不帶數據庫)

SpringBoot+Mybatis+PostMan(八):用戶角色權限訪問控制一(數據庫用戶角色表查詢組合)

SpringBoot+Mybatis+PostMan(九):用戶角色權限訪問控制二(加入資源表和資源角色對應表)

SpringBoot+Mybatis+PostMan(十):用戶角色權限訪問控制三(禁用session、啟用token並集成redis)

 

當我們訪問某個網站時,我們首先只能進入到登陸頁面,系統其他頁面時訪問不進去的,所以這里需要通過攔截器實現攔截功能,只能對外界暴露注冊和登陸頁面,其余頁面一律攔截住。用戶登陸時將信息傳遞到服務器端,服務器會查詢此用戶在服務器是否有session,如果沒有,那么就將用戶攔截在登陸頁面,如果用戶信息在服務器端時存在的,那么服務器端為其開辟一個session內存,並為其生成一個sessionID。

這里用到的知識有攔截器、token認證等等,接下來就進行token認證過程。

項目代碼獲取地址:https://github.com/yeyuting-1314/testdemo_insert_page_token.git

一、准備工作

1. 首先添加依賴,這里攔截需要用到JWT工具,需要我們手工導入

 <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

2. 接下來實現token工具類,實現token生成、獲取特定屬性、獲取請求,以及獲取到token。

@Component
public class TokenUtil {
    /*
    * 生成token
    * */
    public String generateToken(User user){
        Date start  = new Date() ;
        long currentTime = System.currentTimeMillis() + 60*60*1000 ; //一小時的有效時間
        Date end = new Date(currentTime) ;
        String token = "" ;
        token = JWT.create()
                .withAudience(Integer.toString(user.getId()))
                .withAudience(user.getUserName())
                .withIssuedAt(start)
                .withExpiresAt(end)
                .sign(Algorithm.HMAC256(user.getPassword()));
        return token ;
    }

    /*
    * 獲取指定token中某個屬性值
    * */
    public static String get(String token , String key){
        List<String> list = JWT.decode(token).getAudience() ;
        String userId = list.get(0) ;
        return userId ;
    }
    /*
    * 獲取request
    * */
    public static HttpServletRequest getRequest(){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes == null ? null : requestAttributes.getRequest() ;
    }

    /*
    * 獲取token
    * */
    public String getToken(HttpServletRequest request)  {
        Cookie[] cookies = request.getCookies() ;
        for(Cookie c : cookies){
            if(c.getName() == "token"){
                return c.getValue() ;
            }
        }
        return null ;
    }

}

3. 自定義攔截器類,preHandle這個方法會業務層執行前先行執行,用於檢查該請求是否帶有token,如果有的話就放行,讓其進行token認證,如果沒有的話就攔截住,重定向到登陸頁面(一般這種情況值我們要訪問除了login和loginCheck兩個頁面的其他頁面時,會被攔截住,重定向到登陸頁面,后面會有演示)

//自定義攔截器類

public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired TokenUtil tokenUtil ;

    @Override
    public boolean preHandle (HttpServletRequest request ,
                              HttpServletResponse response , Object o )throws Exception{
        //檢查請求中是否存在token , 如果不存在就直接跳轉到登陸頁面
        String token = tokenUtil.getToken(request) ;
        if(StringUtil.isEmpty(token)){
            System.out.println("不存在token");
            response.sendRedirect("/login");
            return false ;
        }
        return true ;
    }


}

4. 攔截器實現,將需要攔截的頁面進行相應攔截

@Configuration
public class MVCConfig implements WebMvcConfigurer {


    @Bean
    public HandlerInterceptor authenticationInterceptor(){

        return new AuthenticationInterceptor();
    }
    /*
    * 靜態資源映射
    * */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/") ;
    }
    @Override
    public void addInterceptors (InterceptorRegistry registry){
       registry.addInterceptor(authenticationInterceptor())
                //表示攔截所有請求
                .addPathPatterns("/*")
                //表示取消對特定路徑的攔截
                .excludePathPatterns("/login")
                .excludePathPatterns("/loginCheck");
                //這里一定不要寫成/**/*.js的形式,spring boot無法識別
                //取消對static目錄下靜態資源的攔截
               // .excludePathPatterns("/static/**") ;
    }

}

二、 這樣一來准備工作就做好了,接下來就是業務層的實現了。

 1. controller層實現

@GetMapping("/login")
    public String test1(){
        System.out.println(PropertiesUtil.class.getClassLoader().
                getResource("").getPath());
        return "登陸界面" ;
    }

    @PostMapping("/loginCheck")
    @ResponseBody
    public  Result login(@RequestBody User user , HttpServletResponse response){
        Result result = userService.loginCheck(user , response) ;
        return result ;
    }

2. service層

public Result loginCheck(User user , HttpServletResponse response);
public Result loginCheck(User user , HttpServletResponse response){
        User user1 = userMapper.selectByName(user.getUserName()) ;
        if(user1 == null ){
            //response.sendRedirect("/login");
            return Results.failure("用戶不存在,") ;
        }
        if(!user1.getPassword().equals(user.getPassword())){
            return Results.failure("密碼輸入錯誤") ;
        }
        String token = tokenUtil.generateToken(user1) ;
        System.out.println("token:" + token);
        Cookie cookie = new Cookie("token" , token) ;
        // 設置cookie的作用域:為”/“時,以在webapp文件夾下的所有應用共享cookie
        cookie.setPath("/");
        response.addCookie(cookie);
        System.out.println("cookie:"+cookie);
        return Results.success("登陸成功") ;

    }

這樣一來,業務層代碼邏輯也書寫完畢,接下來利用postman實現前端模擬。

數據庫內容如下:

 1. 若訪問除了login和loginCheck外的其他頁面,會被攔截回到登陸頁面。

 

 2. 如果用戶名正確密碼錯誤:

 

 3. 用戶名不存在

 

 4. 用戶名密碼均正確,成功登陸。

 這樣一來,token認證登陸這一功能就實現了。

至此,結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM