站点介绍
一、SpringBoot 整合阿里云服务 -- 信息 服务1、简介 信息 服务(Short Message Service)是指通过调用信息 发送API,将指定信息 内容发送给指定手机玩家 。信息 的内容多用来 企业向玩家 传递验证码、系统通知、会员服务等信息 。
2、开通信息 服务(1)进入阿里云官方网站 ,找到 信息 服务
(2)进入 信息 服务 控制台
(3)开通信息 服务(发信息 要收费的)
(4)添加信息 模板管理
用来 定义信息 主体内容。
Step1:选择中国 信息 --》模板管理 --》添加模板
Step2:
填编辑 模板有关 信息 ,并等待审核(审核申请通过 后就可以 使用)。
(5)添加信息 签名管理
用来 定义信息 签名。
Step1:选择中国 信息 --》签名管理 --》添加签名
Step2:
填编辑 签名有关 信息 ,并等待审核(审核申请通过 后就可以 使用)。
(6)简单测试一下
输出格式如下图所示:
【签名】 + 模板
【后台管理系统】您的验证码758644,该验证码5分钟内有效,请勿泄漏于他人!点一下 发送信息 ,该手机号就可以 接收到信息 。
3、SpringBoot 整合信息 服务【参考文档:】 包。
!-- aliyun sms --dependency groupIdcom.aliyun/groupId artifactIdaliyun-java-sdk-core/artifactId version4.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 { @Autowired private SmsUtil smsUtil; @ApiOperation(value = "测试信息 发送功能") @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 --dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.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 = "获得 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 资料 。