国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > SpringBoot+Vue+ElementUI實現(xiàn)后臺管理系統(tǒng)模板(附代碼地址)

SpringBoot+Vue+ElementUI實現(xiàn)后臺管理系統(tǒng)模板(附代碼地址)

時間:2023-06-12 03:15:01 | 來源:網(wǎng)站運營

時間:2023-06-12 03:15:01 來源:網(wǎng)站運營

SpringBoot+Vue+ElementUI實現(xiàn)后臺管理系統(tǒng)模板(附代碼地址):

一、SpringBoot 整合阿里云服務(wù) -- 短信服務(wù)

1、簡介

  短信服務(wù)(Short Message Service)是指通過調(diào)用短信發(fā)送API,將指定短信內(nèi)容發(fā)送給指定手機用戶。短信的內(nèi)容多用于企業(yè)向用戶傳遞驗證碼、系統(tǒng)通知、會員服務(wù)等信息。

2、開通短信服務(wù)

(1)進入阿里云官網(wǎng),找到 短信服務(wù)

【官網(wǎng)地址:】 https://www.aliyun.com/【官方文檔:】 https://help.aliyun.com/product/44282.html 【使用流程參考文檔:】 https://help.aliyun.com/document_detail/59210.html(2)進入 短信服務(wù) 控制臺

(3)開通短信服務(wù)(發(fā)短信要收費的)

(4)添加短信 模板管理

用于定義短信主體內(nèi)容。

Step1:選擇國內(nèi)消息 --》模板管理 --》添加模板

Step2:  

填寫模板相關(guān)信息,并等待審核(審核通過后即可使用)。

(5)添加短信 簽名管理  

用于定義短信簽名。

Step1:選擇國內(nèi)消息 --》簽名管理 --》添加簽名

Step2:  

填寫簽名相關(guān)信息,并等待審核(審核通過后即可使用)。

(6)簡單測試一下

輸出格式如下圖所示:    

【簽名】 + 模板

【后臺管理系統(tǒng)】您的驗證碼758644,該驗證碼5分鐘內(nèi)有效,請勿泄漏于他人!點擊發(fā)送短信,該手機號即可接收到短信。

3、SpringBoot 整合短信服務(wù)

【參考文檔:】 https://help.aliyun.com/document_detail/112148.html(1)引入依賴:引入 短信服務(wù)所需的 jar 包。

<!-- aliyun sms --><dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.1</version></dependency>(2)編寫配置信息

# 阿里云配置信息aliyun: # common 配置信息 accessKeyId: LTAI4GEWZbLZocBzXKYEfmmq accessKeySecret: rZLsruKxWex2qGYVA3UsuBgW5B3uJQ # SMS 短信服務(wù) regionId: cn-hangzhou signName: 后臺管理系統(tǒng) templateCode: SMS_194050461(3)編寫一個工具類 SmsUtil.java 用來操作短信發(fā)送。短信發(fā)送參數(shù):  

需要使用 AccessKey,可參考:
https://www.cnblogs.com/l-y-h/p/13202746.html#_label0_1  

需要使用 SignName,在網(wǎng)站中申請的簽名模板(比如:后臺管理系統(tǒng))?! ?br>
需要使用 TemplateCode,在網(wǎng)站中申請的模板 CODE(比如:SMS_194050461)?! ?br>
需要使用 PhoneNumbers,用來接收驗證碼的手機號?! ?br>
需要使用 TemplateParam,json 形式,用于保存驗證碼。

注:使用 AccessKey 時需要給其開通 發(fā)送短信的權(quán)限。

package com.lyh.admin_template.back.common.utils;import com.aliyuncs.CommonRequest;import com.aliyuncs.CommonResponse;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.http.MethodType;import com.aliyuncs.profile.DefaultProfile;import com.lyh.admin_template.back.modules.sms.entity.SmsResponse;import lombok.Data;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;/** * sms 短信發(fā)送工具類 */@Data@Componentpublic class SmsUtil { @Value("${aliyun.accessKeyId}") private String accessKeyId; @Value("${aliyun.accessKeySecret}") private String accessKeySecret; @Value("${aliyun.signName}") private String signName; @Value("${aliyun.templateCode}") private String templateCode; @Value("${aliyun.regionId}") private String regionId; private final static String OK = "OK"; /** * 發(fā)送短信 */ public boolean sendSms(String phoneNumbers) { if (StringUtils.isEmpty(phoneNumbers)) { return false; } DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); // 固定參數(shù),無需修改 request.setSysMethod(MethodType.POST); request.setSysDomain("dysmsapi.aliyuncs.com"); request.setSysVersion("2017-05-25"); request.setSysAction("SendSms"); request.putQueryParameter("RegionId", regionId); // 設(shè)置手機號 request.putQueryParameter("PhoneNumbers", phoneNumbers); // 設(shè)置簽名模板 request.putQueryParameter("SignName", signName); // 設(shè)置短信模板 request.putQueryParameter("TemplateCode", templateCode); // 設(shè)置短信驗證碼 request.putQueryParameter("TemplateParam", "{/"code/":" + getCode() +"}"); try { CommonResponse response = client.getCommonResponse(request); System.out.println(response.getData()); // 轉(zhuǎn)換返回的數(shù)據(jù)(需引入 Gson 依賴) SmsResponse smsResponse = GsonUtil.fromJson(response.getData(), SmsResponse.class); // 當 message 與 code 均為 ok 時,短信發(fā)送成功、否則失敗 if (SmsUtil.OK.equals(smsResponse.getMessage()) && SmsUtil.OK.equals(smsResponse.getCode())) { return true; } return false; } catch (Exception e) { throw new RuntimeException(e); } } /** * 獲取 6 位驗證碼 */ public String getCode() { return String.valueOf((int)((Math.random()*9+1)*100000)); }}在上面代碼中,為了更好地獲取到返回數(shù)據(jù),使用 Gson 對其數(shù)據(jù)進行轉(zhuǎn)換(之前博客中已有介紹,此處直接使用,可參考:
https://www.cnblogs.com/l-y-h/p/13163653.html#_label1_1),生成 SmsResponse 實例,再根據(jù) SmsResponse 實例數(shù)據(jù)進行相關(guān)處理。

package com.lyh.admin_template.back.modules.sms.entity;import lombok.Data;/** * 用于接收并轉(zhuǎn)換 sms 返回的數(shù)據(jù) */@Datapublic class SmsResponse { private String Message; private String RequestId; private String Code; private String BizId;}(4)編寫一個代碼 TestSMSController.java 測試一下。

package com.lyh.admin_template.back.modules.sms.controller;import com.lyh.admin_template.back.common.utils.Result;import com.lyh.admin_template.back.common.utils.SmsUtil;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/sms")@Api(tags = "短信發(fā)送")public class TestSMSController { @Autowired private SmsUtil smsUtil; @ApiOperation(value = "測試短信發(fā)送功能") @ApiImplicitParam(name = "phoneNumber", required = true, value = "手機號", paramType = "query", dataType = "String") @PostMapping("/testSend") public Result testSend(@RequestParam String phoneNumber) { if (smsUtil.sendSms(phoneNumber)) { return Result.ok().message("短信發(fā)送成功"); } return Result.error().message("短信發(fā)送失敗"); }}

二、SpringBoot 整合 JWT 單點登錄

1、簡單了解下概念(session、SSO、token)

  開發(fā)過程中,前后端通過 http 協(xié)議進行數(shù)據(jù)交互。而 http 是一種無狀態(tài)的協(xié)議,也即客戶端(瀏覽器)每次請求都會被服務(wù)器獨立處理,每個請求間沒有任何關(guān)系。  這就導(dǎo)致了一個問題:服務(wù)器如何知道某個請求是哪個客戶端(用戶)發(fā)送的?

(1)解決方法一:既然 http 無狀態(tài),那自己主動讓服務(wù)器與客戶端同時維護某個用戶狀態(tài)即可?! ∽畛S玫木褪?session。

session 使用流程:  

Step1:用戶登錄,客戶端向服務(wù)器發(fā)送用戶名、密碼等用戶信息。  

Step2:服務(wù)器驗證數(shù)據(jù),并將通過驗證的用戶信息保存在 session 中?! ?br>
Step3:服務(wù)器響應(yīng)請求,并將 session_id 返回給客戶端。  

Step4:客戶端接收返回數(shù)據(jù),并將 session_id 保存在 cookie 中。  

Step5:下一次客戶端發(fā)送請求時,會從 cookie 中取出 session_id 并發(fā)給服務(wù)器。  

Step6:服務(wù)器通過 session_id 找到相應(yīng)的 session 數(shù)據(jù),解析出用戶信息,從而知道是哪個客戶端(用戶)發(fā)送的請求。

session 分析:由于需要在服務(wù)器中進行存儲,若用戶數(shù)量過多,會消耗很多存儲空間。且通常一個復(fù)雜的業(yè)務(wù)中一個請求會進行多次轉(zhuǎn)發(fā)操作,每次都需要經(jīng)過 session_id 查詢 session 數(shù)據(jù)的操作,無異于增加服務(wù)器壓力?!?br>
具有局限性,適用于傳統(tǒng)的單一服務(wù)器模式。如果服務(wù)器是使用集群的方式部署,那么就需要對 session 進行共享處理。

對于多服務(wù)器模式,有什么好的登錄方案嗎?

可以使用 單點登錄 方式解決。

(2)解決方法二:  

單點登錄(Single Sign On),簡稱 SSO,指的是在多個系統(tǒng)中,用戶只需要登錄一次,就可以訪問所有相互信任的系統(tǒng)。也即 對于多個系統(tǒng)不用重復(fù)進行登錄操作。

SSO 使用流程:  

Step1:用戶第一次訪問系統(tǒng)時,由于還未登錄,會被轉(zhuǎn)向登錄界面用于用戶登錄?! ?br>
Step2:用戶信息發(fā)送到認證服務(wù)器,并對其進行校驗,通過后返回一個認證信息(令牌)。

Step3:用戶再次訪問系統(tǒng)時,帶上這個令牌,作為認證依據(jù)?! ?br>
Step4:系統(tǒng)服務(wù)器接收請求后,將令牌發(fā)給認證服務(wù)器進行校驗,若通過校驗則可以訪問系統(tǒng)服務(wù)器。

sso 分析:  

用戶信息可以在認證服務(wù)器獨立保存,便于分布式部署,也可以自定義安全策略。但同時增加了認證服務(wù)器的壓力。常見 sso 實現(xiàn)機制即為 token。

(3)解決方法三:  

基于 token 實現(xiàn)單點登錄。簡單理解:令牌,是由服務(wù)端生成的一串字符串,作為客戶端進行請求的一個標識。

token 使用流程:  

Step1:用戶登錄,客戶端向服務(wù)器發(fā)送用戶名、密碼等用戶信息。  

Step2;服務(wù)器驗證數(shù)據(jù),并將驗證通過的數(shù)據(jù)生成一個 token(加密字符串)?! ?br>
Step3:服務(wù)器響應(yīng)請求,并將 token 返回給客戶端。  

Step4:客戶端接收返回數(shù)據(jù),將 token 保存在 cookie 或者 localStorage、sessionStorage 中?! ?br>
Step5:下一次客戶端發(fā)送請求時,會帶上這個 token?! ?br>
Step6:服務(wù)器驗證 token,從而獲取用戶數(shù)據(jù)。

注:通過 token 與 session 的使用流程比較,實現(xiàn)邏輯看起來是類似的。但是還是有區(qū)別的。使用 token 時不需在服務(wù)器存儲用戶信息,直接從 token 中就可以解析出用戶信息。session 需要在服務(wù)器存儲用戶信息(多個服務(wù)器時需要實現(xiàn) session 共享,否則多個系統(tǒng)需要進行多次登錄)。所以使用 token 便于拓展業(yè)務(wù)(不需要知道在哪個服務(wù)器進行登錄操作)。

token 分析:  

token 無狀態(tài)、且不需要將信息存儲在 session 中,便于擴展。但是由于 token 存儲在客戶端,服務(wù)端無法對其進行銷毀(可以設(shè)置過期時間)。

采用 token,可以自定義 加密、解密字符串的 規(guī)則,但是為了標準化,就得引入 JWT。

(4)解決方法四:  

使用 JWT 實現(xiàn) token。  

服務(wù)器驗證數(shù)據(jù)通過后,將數(shù)據(jù)封裝成 json 對象并發(fā)送給用戶(token)?! ?br>
客戶端接收 JWT 后將其存儲 cookie 或者 localstorage、sessionstorage 中。  

下次請求時,可以將 cookie 作為 HTTP Header 數(shù)據(jù)發(fā)送或者 POST 請求主體數(shù)據(jù)發(fā)送。

2、簡單了解一下 JWT

(1)什么是 JWT?  

JWT(JSON Web Token),即使用 Json 數(shù)據(jù)作為 web 網(wǎng)絡(luò)層的令牌機制。是 Java 實現(xiàn) token 的一種具體解決方案。JWT 可以使用 HMAC 算法或者是 RSA 的公私秘鑰對進行簽名,防止數(shù)據(jù)偽造。

(2)透明令牌 與 自包含令牌的區(qū)別:  

引用(透明)令牌(reference token):指令牌存儲的是數(shù)據(jù)標識符,數(shù)據(jù)內(nèi)容存儲在其他地方。也即隨機生成一個 字符串(uuid 等)作為令牌,不清楚該令牌的具體含義,只有通過 字符串 訪問數(shù)據(jù)內(nèi)容才能得到具體信息。可以類比為 session_id 的使用?! ?br>
自包含令牌(Self-contained token):指令牌存儲的是數(shù)據(jù)(必要且不隱私的數(shù)據(jù)),通過解析令牌即可得到相關(guān)數(shù)據(jù)。此處使用的 JWT 即為一種自包含令牌。

(3)JWT 優(yōu)點:數(shù)據(jù)量小、簡潔,可以通過URL、 POST 參數(shù)、HTTP Header 發(fā)送,傳輸速度快。自包含了數(shù)據(jù),解析字符串即可獲取想要的數(shù)據(jù),避免與數(shù)據(jù)庫進行交互。token 以加密形式保存在客戶端,不需要保存在服務(wù)端,易于擴展。

(4)JWT 組成  

JWT 是一個很長的字符串,由三部分組成,并使用 點(.) 隔開。  

Header.Payload.Signature,即 JWT 頭.有效載荷.簽名。

Header:用于存儲 JWT 元數(shù)據(jù),是一個 JSON 對象。其中 alg 表示加密算法(HS256、RS256)。typ 表示 token 類型。

{ "alg": "HS256", "typ": "JWT"}【注:】 HS256 指的是 HMAC SHA256(默認),一種對稱算法,采用同一個密鑰生成、驗證簽名。 RS256 指的是 RSA SHA256,一種非對稱算法,采用私鑰生成簽名,用公鑰驗證簽名。Payload:  

用于存放需要傳遞的數(shù)據(jù)(用戶信息)。  

其包含一些默認字段,也可以自定義字段(不建議存儲私密數(shù)據(jù),易泄露)。

【默認字段:】iss:發(fā)行人(JWT 生成的一方)exp:過期時間(要大于 iat)sub:主題aud:用戶(接收 JWT 的一方)nbf:在此時間之前 JWT 不可用iat:JWT 發(fā)布時間jti:JWT ID用于標識該JWTSignature:  

用于存放簽名信息?! ?br>
指定一個 密碼(secret,不能公開給用戶,保存在服務(wù)端),按如下公式生成。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(claims), secret)【理解:】 對 header、payload 分別進行 Base64URL 加密,使用 點(.)連接。 并根據(jù) header 中指定的 加密算法,使用 secret 對數(shù)據(jù)再次加密。注: 由于 JWT 可以放在 URL 中(比如:/home?token=xxx), 由于 Base64 中 =、+、/ 在 url 中有特殊含義,使用 base64 生成的 token 會出現(xiàn)問題。 Base64url 對這些符號進行了轉(zhuǎn)換,(去掉 =,用 - 替換 +, 用 _ 替換 /).

3、SpringBoot 整合 JWT

(1)添加依賴

<!-- JWT --><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version></dependency>(2)創(chuàng)建一個工具類(JwtUtil.java)用于操作 JWT。

package com.lyh.admin_template.back.common.utils;import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jws;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import org.apache.commons.lang3.StringUtils;import javax.servlet.http.HttpServletRequest;import java.util.Date;/** * JWT 操作工具類 */public class JwtUtil { // 設(shè)置過期時間(15 分鐘) public static final long EXPIRE = 1000 * 60 * 15; // 設(shè)置 jwt 生成 secret(隨意指定) public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; /** * 生成 jwt token */ public static String getJwtToken(String userId, String userName) { String JwtToken = Jwts.builder() // 設(shè)置 jwt 類型 .setHeaderParam("typ", "JWT") // 設(shè)置 jwt 加密方法 .setHeaderParam("alg", "HS256") // 設(shè)置 jwt 主題 .setSubject("admin-user") // 設(shè)置 jwt 發(fā)布時間 .setIssuedAt(new Date()) // 設(shè)置 jwt 過期時間 .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) // 設(shè)置自定義數(shù)據(jù) .claim("userId", userId) .claim("userName", userName) // 設(shè)置密鑰與算法 .signWith(SignatureAlgorithm.HS256, APP_SECRET) // 生成 token .compact(); return JwtToken; } /** * 判斷token是否存在與有效,true 表示未過期,false 表示過期或不存在 */ public static boolean checkToken(String jwtToken) { if (StringUtils.isEmpty(jwtToken)) { return false; } try { // 獲取 token 數(shù)據(jù) Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); // 判斷是否過期 return claimsJws.getBody().getExpiration().after(new Date()); } catch (Exception e) { throw new RuntimeException(e); } } /** * 判斷token是否存在與有效 */ public static boolean checkToken(HttpServletRequest request) { return checkToken(request.getHeader("token")); } /** * 根據(jù) token 獲取數(shù)據(jù) */ public static Claims getTokenBody(HttpServletRequest request) { return getTokenBody(request.getHeader("token")); } /** * 根據(jù) token 獲取數(shù)據(jù) */ public static Claims getTokenBody(String jwtToken) { if (StringUtils.isEmpty(jwtToken)) { return null; } Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); return claimsJws.getBody(); }}(3)編寫一個測試類(TestJWTController.java) ,用于測試

package com.lyh.admin_template.back.controller.test;import com.lyh.admin_template.back.common.utils.JwtUtil;import com.lyh.admin_template.back.common.utils.Result;import io.jsonwebtoken.Claims;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping("/test/jwt")@RestController@Api(tags = "測試 JWT")public class TestJWTController { @ApiOperation(value = "獲取 token") @PostMapping("/getToken") public Result testJwt() { return Result.ok().data("token", JwtUtil.getJwtToken("1", "tom")); } @ApiOperation(value = "測試是否過期") @PostMapping("/testExpire") public Result testJwtExpire(String jwtToken) { if (JwtUtil.checkToken(jwtToken)) { Claims claims = JwtUtil.getTokenBody(jwtToken); return Result.ok().message("token 未過期").data("claims", claims); } return Result.ok().message("token 已過期"); }}測試結(jié)果如下:  定義過期時間為 30s,未過期時,返回 json 數(shù)據(jù)。

來源:
https://www.cnblogs.com/l-y-h/p/13214493.html
GitHub地址:
https://github.com/lyh-man/admin-vue-template.git

關(guān)鍵詞:模板,地址,系統(tǒng),管理,實現(xiàn),后臺

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉