日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

完成单点登录

發布時間:2024/4/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 完成单点登录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

編寫登錄接口

接下來,我們需要在auth編寫一個接口,對外提供登錄授權服務。基本流程如下:

  • 客戶端攜帶用戶名和密碼請求登錄

  • 授權中心調用用戶中心接口,根據用戶名和密碼查詢用戶信息

  • 如果用戶名密碼正確,能獲取用戶,否則登錄失敗

  • 如果校驗成功,則生成JWT并返回

編寫遠程調用接口

創建ums-interface工程:

pom.xml中的依賴,參照其他interface工程。并在ums和auth工程中引入該接口工程

UmsApi:

public interface UmsApi {/*** 根據用戶名和密碼查詢用戶* @param username* @param password* @return*/@GetMapping("ums/member/query")public Resp<MemberEntity> queryUser(@RequestParam("username") String username,@RequestParam("password") String password); }

生成公鑰和私鑰

我們需要在授權中心生成真正的公鑰和私鑰。我們必須有一個生成公鑰和私鑰的secret,這個可以配置到application.yml中:

jwt:pubKeyPath: C:\\tmp\\rsa\\rsa.pub # 公鑰地址priKeyPath: C:\\tmp\\rsa\\rsa.pri # 私鑰地址secret: sf3423jsdf#3$@FDS32expire: 30 # 過期時間,單位分鐘cookieName: TOKEN

然后編寫屬性類讀取jwt配置,并從秘鑰配置文件中讀取出響應的公鑰及私鑰,加載這些數據:

@Data @Slf4j @ConfigurationProperties(prefix = "jwt") public class JwtProperties {private String secret; // 密鑰private String pubKeyPath;// 公鑰private String priKeyPath;// 私鑰private int expire;// token過期時間private PublicKey publicKey; // 公鑰private PrivateKey privateKey; // 私鑰private String cookieName; // cookie名稱/*** @PostContruct:在構造方法執行之后執行該方法*/@PostConstructpublic void init() {try {File pubKey = new File(pubKeyPath);File priKey = new File(priKeyPath);if (!pubKey.exists() || !priKey.exists()) {// 生成公鑰和私鑰RsaUtils.generateKey(pubKeyPath, priKeyPath, secret);}// 獲取公鑰和私鑰this.publicKey = RsaUtils.getPublicKey(pubKeyPath);this.privateKey = RsaUtils.getPrivateKey(priKeyPath);} catch (Exception e) {log.error("初始化公鑰和私鑰失敗!", e);throw new RuntimeException();}} }

AuthController

編寫授權接口,我們接收用戶名和密碼,校驗成功后,寫入cookie中。

  • 請求方式:post

  • 請求路徑:/auth/accredit

  • 請求參數:username和password

  • 返回結果:無

代碼:

@RestController @RequestMapping("auth") @EnableConfigurationProperties(JwtProperties.class) public class AuthController {@Autowiredprivate AuthService authService;@Autowiredprivate JwtProperties jwtProperties;/*** 登錄授權** @param username* @param password* @return*/@PostMapping("accredit")public Resp<Object> authentication(@RequestParam("username") String username,@RequestParam("password") String password,HttpServletRequest request,HttpServletResponse response) {// 登錄校驗String token = this.authService.authentication(username, password);if (StringUtils.isBlank(token)) {return Resp.fail("登錄失敗,用戶名或密碼錯誤");}// 將token寫入cookie,并指定httpOnly為true,防止通過JS獲取和修改CookieUtils.setCookie(request, response, jwtProperties.getCookieName(), token, jwtProperties.getExpire());return Resp.ok("登錄成功");} }

AuthService

在auth-service:

@Service public class AuthService {@Autowiredprivate UmsClient umsClient;@Autowiredprivate JwtProperties jwtProperties;public String authentication(String username, String password) {try {// 調用微服務,執行查詢Resp<MemberEntity> resp = this.umsClient.queryUser(username, password);MemberEntity memberEntity = resp.getData();// 如果查詢結果為null,則直接返回nullif (memberEntity == null) {return null;}// 如果有查詢結果,則生成tokenMap<String, Object> map = new HashMap<>();map.put("id", memberEntity.getId());map.put("username", memberEntity.getUsername());String token = JwtUtils.generateToken(map, jwtProperties.getPrivateKey(), jwtProperties.getExpire());return token;} catch (Exception e) {e.printStackTrace();}return null;} }

UmsClient

接下來我們肯定要對用戶密碼進行校驗,所以我們需要通過FeignClient去訪問 ums-service微服務:

在auth中引入ums-interface依賴:

<dependency><groupId>com.atguigu</groupId><artifactId>ums-interface</artifactId><version>0.0.1-SNAPSHOT</version> </dependency>

編寫UmsClient:

@FeignClient("ums-service") public interface UmsClient extends UmsApi { }

CookieUtils

要注意,這里我們使用了一個工具類,CookieUtils,可以在課前資料中找到,我們把它添加到core中,然后引入servlet相關依賴即可:

package com.leon.core.utils;import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder;/*** * Cookie 工具類**/ public final class CookieUtils {static final Logger logger = LoggerFactory.getLogger(CookieUtils.class);/*** 得到Cookie的值, 不編碼* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName) {return getCookieValue(request, cookieName, false);}/*** 得到Cookie的值,* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {Cookie[] cookieList = request.getCookies();if (cookieList == null || cookieName == null){return null; }String retValue = null;try {for (int i = 0; i < cookieList.length; i++) {if (cookieList[i].getName().equals(cookieName)) {if (isDecoder) {retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");} else {retValue = cookieList[i].getValue();}break;}}} catch (UnsupportedEncodingException e) {logger.error("Cookie Decode Error.", e);}return retValue;}/*** 得到Cookie的值,* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {Cookie[] cookieList = request.getCookies();if (cookieList == null || cookieName == null){return null; }String retValue = null;try {for (int i = 0; i < cookieList.length; i++) {if (cookieList[i].getName().equals(cookieName)) {retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);break;}}} catch (UnsupportedEncodingException e) {logger.error("Cookie Decode Error.", e);}return retValue;}/*** 生成cookie,并指定編碼* @param request 請求* @param response 響應* @param cookieName name* @param cookieValue value* @param encodeString 編碼*/public static final void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, String encodeString) {setCookie(request,response,cookieName,cookieValue,null,encodeString, null);}/*** 生成cookie,并指定生存時間* @param request 請求* @param response 響應* @param cookieName name* @param cookieValue value* @param cookieMaxAge 生存時間*/public static final void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, Integer cookieMaxAge) {setCookie(request,response,cookieName,cookieValue,cookieMaxAge,null, null);}/*** 設置cookie,不指定httpOnly屬性*/public static final void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, Integer cookieMaxAge, String encodeString) {setCookie(request,response,cookieName,cookieValue,cookieMaxAge,encodeString, null);}/*** 設置Cookie的值,并使其在指定時間內生效* * @param cookieMaxAge* cookie生效的最大秒數*/public static final void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, Integer cookieMaxAge, String encodeString, Boolean httpOnly) {try {if(StringUtils.isBlank(encodeString)) {encodeString = "utf-8";}if (cookieValue == null) {cookieValue = "";} else {cookieValue = URLEncoder.encode(cookieValue, encodeString);}Cookie cookie = new Cookie(cookieName, cookieValue);if (cookieMaxAge != null && cookieMaxAge > 0)cookie.setMaxAge(cookieMaxAge);if (null != request)// 設置域名的cookiecookie.setDomain(getDomainName(request));cookie.setPath("/");if(httpOnly != null) {cookie.setHttpOnly(httpOnly);}response.addCookie(cookie);} catch (Exception e) {logger.error("Cookie Encode Error.", e);}}/*** 得到cookie的域名*/private static final String getDomainName(HttpServletRequest request) {String domainName = null;String serverName = request.getRequestURL().toString();if (serverName == null || serverName.equals("")) {domainName = "";} else {serverName = serverName.toLowerCase();serverName = serverName.substring(7);final int end = serverName.indexOf("/");serverName = serverName.substring(0, end);final String[] domains = serverName.split("\\.");int len = domains.length;if (len > 3) {// www.xxx.com.cndomainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];} else if (len <= 3 && len > 1) {// xxx.com or xxx.cndomainName = domains[len - 2] + "." + domains[len - 1];} else {domainName = serverName;}}if (domainName != null && domainName.indexOf(":") > 0) {String[] ary = domainName.split("\\:");domainName = ary[0];}return domainName;}}

?

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的完成单点登录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。