一、SpringBoot 整合阿里云服务 — 信息服务1、简介信息服务(Short Message Service)是指通过调用信息发送API 。将指定信息内容发送给指定手机玩家。信息的内容多用来企业向玩家传递验证码、系统通知、会员服务等信息。
2、开通信息服务(1)进入阿里云官方网站。找到信息服务

文章插图
(2)进入 信息服务 控制台

文章插图
(3)开通信息服务(发信息要收费的)

文章插图
【springboot SpringBoot+Vue+ElementUI实现后台管理系统模板】

文章插图
(4)添加信息模板管理
用来定义信息主体内容 。
Step1:选择中国信息–》模板管理 –》添加模板

文章插图
Step2:
填编辑模板有关信息。并等待审核(审核申请通过后就可以使用) 。

文章插图
(5)添加信息签名管理
用来定义信息签名 。
Step1:选择中国信息–》签名管理 –》添加签名

文章插图
Step2:
填编辑签名有关信息。并等待审核(审核申请通过后就可以使用) 。

文章插图
(6)简单测试一下
输出格式如下图所示:
【签名】 + 模板
【后台管理系统】您的验证码758644 。该验证码5分钟内有效 。请勿泄漏于他人!点一下发送信息。该手机号就可以接收到信息。

文章插图
3、SpringBoot 整合信息服务【参考文档:】包 。
!– aliyun sms –dependencygroupIdcom.aliyun/groupIdartifactIdaliyun-java-sdk-core/artifactIdversion4.5.1/version/dependency

文章插图
(2)编编辑配置信息
# 阿里云配置信息aliyun: # common 配置信息accessKeyId: LTAI4GEWZbLZocBzXKYEfmmq accessKeySecret: rZLsruKxWex2qGYVA3UsuBgW5B3uJQ # SMS 信息服务 regionId: cn-hangzhou signName: 后台管理系统 templateCode: SMS_194050461

文章插图
(3)编编辑一个工具类 SmsUtil.java 用来操作信息发送 。信息发送参数:
需要使用 AccessKey 。可参考:
需要使用 SignName 。在网址中申请的签名模板(比如:后台管理系统) 。
需要使用 TemplateCode 。在网址中申请的模板 CODE(比如:SMS_194050461) 。
需要使用 PhoneNumbers 。用来接收验证码的手机号 。
需要使用 TemplateParam 。json 形式 。用来保存验证码 。
注:使用 AccessKey 时需要给其开通 发送信息的权限 。

文章插图
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.));}}

文章插图
在上面代码中 。为了更好地获得到返回资料。使用 Gson 对其资料进行转换(之前博客中已有教学。此处直接使用 。可参考: 实例资料进行有关处理 。
package com.lyh.admin_template.back.modules.sms.entity;import lombok.Data;/** * 用来接收并转换 sms 返回的资料*/@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 = "信息发送")public class TestSMSController {@Autowiredprivate SmsUtil smsUtil;@ApiOperation(value = http://www.shenzhoubaby.com/"测试信息发送功能")@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("信息发送成功");}return Result.error().message("信息发送失败");}}

文章插图
二、SpringBoot 整合 JWT 单点登录1、简单知道下概念(session、SSO、token)研究过程中 。前后端通过 是一种无情况的协议 。也即应用(浏览器)每当请求都会被服务器独立处理 。每一个请求间没有任何关系 。这就导致了一个问题:服务器怎么样知道某个请求是哪个应用(玩家)发送的?
(1)解决途径一:既然。
session 使用流程:
Step1:玩家登录 。应用向服务器发送玩家名、密码等玩家信息。
Step2:服务器验证资料。并将通过验证的玩家信息保存在 session 中 。
Step3:服务器响应请求 。并将 session_id 返回给应用。
Step4:应用接收返回资料。并将 session_id 保存在 cookie 中 。
Step5:下一次应用发送请求时 。会从 cookie 中取出 session_id 并发给服务器 。
Step6:服务器通过 session_id 找到相对应的session 资料。解析出玩家信息。从而知道是哪个应用(玩家)发送的请求 。

文章插图
session 解析:由于需要在服务器中进行存储 。若玩家数量过多 。会消耗很多存储空间 。且一般一个杂乱的业务中一个请求会进行多次转发操作 。每当都需要经过session_id 查询 session 资料的操作 。无异于增加服务器压力 。
具有局限性 。适合用来经典的单一服务器模式 。如果服务器是使用集群的方法部署 。那么就需要对 session 进行共享处理 。
对于多服务器模式 。有什么好的登录方案吗?
可以使用 单点登录 方法解决 。
(2)解决途径二:
单点登录(Single Sign On) 。简称 SSO 。指的是在多个系统中 。玩家只要登录一次 。就可以采访任何互相信任的系统 。也即 对于多个系统不用重复进行登录操作 。
SSO 使用流程:
Step1:玩家初次采访系统时 。由于还未登录 。会被转向登录窗口用来玩家登录 。
Step2:玩家信息发送到认证服务器 。并对其进行校验 。通过后返回一个认证信息(令牌) 。
Step3:玩家再一次采访系统时 。带上这个令牌 。作为认证依据 。
Step4:系统服务器接收请求后 。将令牌发给认证服务器进行校验 。若通过校验则可以采访系统服务器 。

文章插图
sso 解析:
玩家信息可以在认证服务器独立保存 。便于分布式部署 。也完全可以自己定义设置安全策略 。但同一时间增加了认证服务器的压力 。常见 sso 实现机制即为 token 。
(3)解决途径三:
基于 token 实现单点登录 。简单理解:令牌 。是由服务端生成的一串字符串 。作为应用进行请求的一个标识 。
token 使用流程:
Step1:玩家登录 。应用向服务器发送玩家名、密码等玩家信息。
Step2;服务器验证资料。并将验证通过的资料生成一个 token(加密字符串) 。
Step3:服务器响应请求 。并将 token 返回给应用。
Step4:应用接收返回资料。将 token 保存在 cookie 或者 localStorage、sessionStorage 中 。
Step5:下一次应用发送请求时 。会带上这个token 。
Step6:服务器验证 token 。从而获得玩家资料。

文章插图
注:通过 token 与 session 的使用流程比较 。实现逻辑就这样看起来是类似的 。但是还是有区其他。使用 token 时不需在服务器存储玩家信息。直接从 token 中就可以解析出玩家信息。session 需要在服务器存储玩家信息(多个服务器时需要实现 session 共享 。不然多个系统需要进行多次登录) 。所以使用 token 便于拓展业务(不需你一定要知道在哪个服务器进行登录操作) 。
token 解析:
token 无情况、且不需要将信息存储在 session 中 。便于扩展 。但是由于 token 存储在应用。服务端无法对其进行销毁(可以设置过期时光) 。
选用token 。可以自己定义设置加密、解密字符串的 规则 。但是为了标准化 。就得引入 JWT 。
(4)解决途径四:
使用 JWT 实现 token 。
服务器验证资料通过后 。将资料封装成 json 对象并发送给玩家(token) 。
应用接收 JWT 后将其存储 cookie 或者 localstorage、sessionstorage 中 。
下次请求时 。可以将 cookie 作为 请求主体资料发送 。
2、简单知道一下 JWT(1)什么是 JWT?
JWT(JSON Web Token) 。即便用 Json 资料作为 web 网上层的令牌机制 。是 Java 实现 token 的一种仔细解决问题方案。JWT 可以使用 Hmac 算法或者是 RSA 的公私秘钥对进行签名 。以免资料伪造 。
(2)透视令牌 与 自包含令牌的区别:
引用(透视)令牌(reference token):指令牌存储的是资料标识符 。资料内容存储在很多地方 。也即随机生成一个 字符串(uuid 等)作为令牌 。不清楚该令牌的仔细含义 。只有通过 字符串 采访资料内容才能获得仔细信息。可以类比为 session_id 的使用 。
自包含令牌(Self-contained token):指令牌存储的是资料(一定且不隐私的资料) 。通过解析令牌就可以获得有关资料。此处使用的 JWT 即为一种自包含令牌 。
(3)JWT 优点:资料量小、简洁 。可以通过URL、 POST 参数、 以加密形式保存在应用。不需要保存在服务端 。易于扩展 。
(4)JWT 组成
JWT 是一个很长的字符串 。由三部分组成 。并使用 点(.) 隔开 。
Header.Payload.Signature 。即 JWT 头.有效载荷.签名 。
Header:用来存储 JWT 元资料。是一个 JSON 对象 。其中alg 表示加密算法(HS256、RS256) 。typ 表示 token 类别。
{ "alg": "HS256", "typ": "JWT"}【注:】HS256 指的是 HMAC SHA256(默认) 。一种对称算法 。选用同一个密钥生成、验证签名 。RS256 指的是 RSA SHA256 。一种非对称算法 。选用私钥生成签名 。用公钥验证签名 。Payload:
用来存放需要传递的资料(玩家信息) 。
其包含有些默认字段 。也完全可以自己定义设置字段(不反馈存储私密资料。易泄露) 。
【默认字段:】iss:发售人(JWT 生成的一方)exp:过期时光(要大于 iat)sub:主题aud:玩家(接收 JWT 的一方)nbf:在此时间之前JWT 不可用iat:JWT 发布时光jti:JWT ID用来标识该JWTSignature:
用来存放签名信息。
指定一个 密码(secret 。不可以公开给玩家。保存在服务端) 。按如下公式生成 。
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(claims), secret)【理解:】对 header、payload 分别进行 Base64URL 加密 。使用 点(.)连接 。并根据 header 中指定的 加密算法 。使用 secret 对资料再一次加密 。注:由于 JWT 可以放在 URL 中(比如:/home?token=xxx) 。由于 Base64 中 =、+、/ 在 url 中有固定含义 。使用 base64 生成的 token 会出现问题 。Base64url 对这些符号进行了转换 。(去掉 = 。用 – 代替+ 。用 _ 代替/).3、SpringBoot 整合 JWT(1)添加依赖
!– JWT –dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.0/version/dependency

文章插图
(2)创建一个工具类(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.();}}

文章插图
(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 = http://www.shenzhoubaby.com/"获得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 已过期");}}测试结果如下:定义过期时光为 30s 。未过期时 。返回 json 资料。

文章插图
