SpringBoot實(shí)現(xiàn)登錄注冊(cè)的三種基本方式
cookie方式實(shí)現(xiàn)
使用前端緩存cookie的方式實(shí)現(xiàn),十分不安全
后端:
<dependencies>
<!-- 其他依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@Controller
public class LoginController {
@GetMapping("/")
public String index() {
return "index";
}
@PostMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpServletResponse response) {
// 進(jìn)行用戶名和密碼的驗(yàn)證邏輯
if (isValidUser(username, password)) {
// 驗(yàn)證通過(guò),創(chuàng)建一個(gè)Cookie保存用戶登錄信息
Cookie cookie = new Cookie("user", username);
cookie.setMaxAge(86400); // 設(shè)置Cookie有效期為1天
response.addCookie(cookie);
// 重定向到登錄成功頁(yè)面
return "redirect:/success";
} else {
// 驗(yàn)證失敗,返回登錄頁(yè)面
return "redirect:/?error=1";
}
}
@GetMapping("/success")
public String success() {
return "success";
}
private boolean isValidUser(String username, String password) {
// 在實(shí)際應(yīng)用中,這里可以進(jìn)行用戶名和密碼的驗(yàn)證邏輯,比如查詢數(shù)據(jù)庫(kù)或調(diào)用API等
// 這里只是一個(gè)示例,始終返回true來(lái)模擬驗(yàn)證通過(guò)
return true;
}
}
前端:
<!DOCTYPE html>
<html>
<head>
<title>Cookie 示例</title>
</head>
<body>
<h1>Cookie 示例</h1>
<script>
function getCookie(name) {
const value = "; " + document.cookie;
const parts = value.split("; " + name + "=");
if (parts.length === 2) {
return parts.pop().split(";").shift();
}
}
function setCookie(name, value, days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
const expires = "expires=" + date.toUTCString();
document.cookie = name + "=" + value + ";" + expires + ";path=/";
}
function updateCookie(name, value) {
document.cookie = name + "=" + value + ";path=/";
}
function deleteCookie(name) {
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;";
}
// 獲取Cookie的值
const username = getCookie("user");
if (username !== undefined) {
console.log("用戶名:", username);
} else {
console.log("用戶未登錄或沒(méi)有保存用戶的Cookie");
}
// 設(shè)置Cookie的值
setCookie("user", "John Doe", 7); // 將用戶的登錄信息保存到Cookie中,有效期為7天
// 修改Cookie的值
updateCookie("user", "Jane Doe"); // 將用戶的用戶名更新為"Jane Doe"
// 刪除Cookie
deleteCookie("user"); // 刪除名為"user"的Cookie
</script>
</body>
</html>session的方式
后端保存會(huì)話(redis),前端發(fā)信息
<!-- Maven 依賴 -->
<dependencies>
<!-- Spring Session -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-session</artifactId>
</dependency>
<!-- Redis 驅(qū)動(dòng) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies># Redis 連接配置 spring.redis.host=localhost spring.redis.port=6379
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@SpringBootApplication
@EnableRedisHttpSession
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}實(shí)現(xiàn)session,Spring 會(huì)自動(dòng)使用 Redis 來(lái)管理 HttpSession。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class MyController {
@GetMapping("/profile")
public String getProfile(HttpSession session) {
// 從會(huì)話中獲取用戶信息
String username = (String) session.getAttribute("username");
if (username != null) {
return "Username: " + username;
} else {
return "Not logged in";
}
}
}前端:
// 后端返回的響應(yīng)中包含 session ID
const sessionID = '1234567890';
// 前端將 session ID 存儲(chǔ)在 LocalStorage 中
localStorage.setItem('sessionID', sessionID);
// 發(fā)送請(qǐng)求時(shí)手動(dòng)將 session ID 攜帶在請(qǐng)求頭中或請(qǐng)求參數(shù)中
fetch('/profile', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('sessionID')
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// 成功獲取到用戶資料信息
console.log(data);
} else {
// 未登錄,進(jìn)行相應(yīng)處理
console.log('未登錄');
}
});jwt方式實(shí)現(xiàn)
特點(diǎn):一次登錄,到處暢通。
使用sso微服務(wù)去認(rèn)證,通過(guò)后保存token,再次驗(yàn)證時(shí)出示憑證即可獲取登錄信息。

1. 添加依賴
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>2.controller:
@RequestMapping("/login")
public Map<String,String> login(String userName, String password){
Map<String,String> map=new HashMap<>();
try{
String token = Jwts.builder().setSubject(userName) //主題,可以放用戶的詳細(xì)信息
.setIssuedAt(new Date()) //token創(chuàng)建時(shí)間
.setExpiration(new Date(System.currentTimeMillis() + 60000)) //token過(guò)期時(shí)間
.setId("userId") //用戶ID
//.setClaims(hashMap) //配置角色信息
.signWith(SignatureAlgorithm.HS256, "WuHan") //加密方式和加密密碼
.compact();
// System.out.println("token:"+token);
map.put("code","1");
map.put("msg","success");
map.put("token",token);
map.put("user",userName);
}catch (Exception e){
map.put("code","0");
map.put("msg","fail");
e.printStackTrace();
}
return map;
}token示例如下:
token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4YyIsImlhdCI6MTU5MTE1NDQwNiwiZXhwIjoxNTkxMTU0NDY2LCJqdGkiOiJ1c2VySWQifQ.c7gCDgIQ_I40dIWRxyG4yd1xaZQyWflnC7kX2Uoc9H8
token構(gòu)成包含三個(gè)部分:
- Header 頭部
- Payload 負(fù)載
- Signature 簽名
注意事項(xiàng):
①根據(jù)需求設(shè)計(jì)過(guò)期時(shí)間(1秒 =1000 毫秒 )
②因?yàn)槲野褧r(shí)間設(shè)計(jì)到token里面了所以你可以測(cè)試每次產(chǎn)生的token不一樣
③設(shè)置userId那一欄-我目前是寫(xiě)死了 setId(“userId”) ,你可以根據(jù)需求設(shè)計(jì)不同的值進(jìn)去
3.校驗(yàn)Token:
try {
JwtParser parser = Jwts.parser();
parser.setSigningKey("WuHan");//解析 要和上面“暗號(hào)”一樣
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
Claims body = claimsJws.getBody();
String username = body.getSubject();
// Object role = body.get("role");
return true;
} catch (ExpiredJwtException e) {
e.printStackTrace();
} catch (UnsupportedJwtException e) {
e.printStackTrace();
} catch (MalformedJwtException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}setSigningKey()與builder中簽名方法signWith()對(duì)應(yīng),parser中的此方法擁有與signWith()方法相同的三種參數(shù)形式,用于設(shè)置JWT的簽名key,用戶后面對(duì)JWT進(jìn)行解析。
isSigned() 校驗(yàn)JWT是否進(jìn)行簽名。方法很簡(jiǎn)單,以分隔符" . ",截取JWT第三段,即簽名部分進(jìn)行判斷。
前端:
<script type="text/javascript">
$("#login").click(function () {
var name=$("#userName").val();
var pwd=$("#password").val();
$.post("http://localhost:8080/user/login",{userName:name,password:pwd},function(data) {
console.log(data);
if(data.code=="1"){
/* document.cookie=data.token;*/
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("user",data.user);
window.location.href="index.html" rel="external nofollow" ;
}else{
window.location.href="login.html" rel="external nofollow" rel="external nofollow" ;
}
},"json");
});
</script>
//需要驗(yàn)證token的頁(yè)面
<script>
var data = sessionStorage.getItem("token");
if(data==null){
window.location.href="login.html" rel="external nofollow" rel="external nofollow" ;
}
</script>補(bǔ)充:
window.sessionStorage(session級(jí)別):暫時(shí)儲(chǔ)存,瀏覽器關(guān)閉之后會(huì)清除
window.localStorage (namespace級(jí)別):本地儲(chǔ)存,瀏覽器關(guān)閉之后依舊不會(huì)清除,只能人為刪除
4.開(kāi)啟登錄攔截器
/**
* 登錄攔截
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
try {
JwtParser parser = Jwts.parser();
parser.setSigningKey("WuHan");
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
Claims body = claimsJws.getBody();
String username = body.getSubject();
Object role = body.get("role");
return true;
} catch (ExpiredJwtException e) {
e.printStackTrace();
} catch (UnsupportedJwtException e) {
e.printStackTrace();
} catch (MalformedJwtException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}5.加載攔截器
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Resource
private LoginInterceptor loginInterceptor;
/**
* 添加攔截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//.execudePathPatterns()//可以添加不攔截的地址
registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
}
}到此這篇關(guān)于SpringBoot實(shí)現(xiàn)登錄注冊(cè)的三種基本方式的文章就介紹到這了,更多相關(guān)SpringBoot 登錄 注冊(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot常見(jiàn)登錄(注冊(cè))幾種實(shí)現(xiàn)過(guò)程
- SpringBoot整合MD5加密完成注冊(cè)和登錄方式
- Springboot集成JWT實(shí)現(xiàn)登錄注冊(cè)的示例代碼
- SpringBoot結(jié)合JWT實(shí)現(xiàn)用戶登錄、注冊(cè)、鑒權(quán)
- 基于SpringBoot和Vue3的博客平臺(tái)的用戶注冊(cè)與登錄功能實(shí)現(xiàn)
- SpringBoot+JWT實(shí)現(xiàn)注冊(cè)、登錄、狀態(tài)續(xù)簽流程分析
- SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn)
- springboot+VUE實(shí)現(xiàn)登錄注冊(cè)
- SpringBoot實(shí)現(xiàn)登錄注冊(cè)常見(jiàn)問(wèn)題解決方案
相關(guān)文章
Java代碼格式化工具(PMD,Checkstyle)的學(xué)習(xí)指南
在?Java?開(kāi)發(fā)的旅程中,編寫(xiě)整潔、規(guī)范的代碼是每個(gè)開(kāi)發(fā)者追求的目標(biāo),本文將深入探討?PMD?和?Checkstyle?的功能,使用方法以及它們?nèi)绾螏椭覀冏尨a煥然一新吧2025-05-05
SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)動(dòng)態(tài)權(quán)限問(wèn)題
這篇文章主要介紹了SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)-動(dòng)態(tài)權(quán)限,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換
本文主要介紹了SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03
搭建簡(jiǎn)單的Spring-Data JPA項(xiàng)目
本文主要介紹了搭建簡(jiǎn)單的Spring-Data JPA項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Spring Controller接收前端JSON數(shù)據(jù)請(qǐng)求方式
這篇文章主要為大家介紹了Spring Controller接收前端JSON數(shù)據(jù)請(qǐng)求方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
詳談java中int和Integer的區(qū)別及自動(dòng)裝箱和自動(dòng)拆箱
這篇文章主要介紹了詳談java中int和Integer的區(qū)別及自動(dòng)裝箱和自動(dòng)拆箱,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot整合mybatis-plus快速入門(mén)超詳細(xì)教程
mybatis-plus 是一個(gè) Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生,本文給大家分享SpringBoot整合mybatis-plus快速入門(mén)超詳細(xì)教程,一起看看吧2021-09-09
Java輸入數(shù)據(jù)的知識(shí)點(diǎn)整理
在本篇文章里小編給大家整理的是關(guān)于Java如何輸入數(shù)據(jù)的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們學(xué)習(xí)參考下。2020-01-01

