硅谷课堂 12_公众号消息和微信授权登录
硅谷课堂第十二天-公众号消息和微信授权登录
文章目录
- 硅谷课堂第十二天-公众号消息和微信授权登录
- 一、公众号普通消息
- 1、实现目标
- 2、消息接入
- 2.1、公众号服务器配置
- 2.2、验证来自微信服务器消息
- 2.3、消息接收
- 3、配置内网穿透(ngrok)
- 3.1、注册用户
- 3.2、实名认证
- 3.3、开通隧道
- 3.4、启动隧道
- 3.5、测试
- 4、消息业务实现
- 4.1、service_vod模块创建接口
- 4.2、创建模块定义接口
- 4.3、service_wechat引入依赖
- 4.4、service_wechat模块实现方法
- 4.5、更改MessageController方法
- 5、测试公众号消息
- 二、公众号模板消息
- 1、实现目标
- 2、模板消息实现
- 3、申请模板消息
- 4、添加模板消息
- 5、公众号测试号申请模板消息
- 5.1、新增测试模板
- 5.2、填写信息
- 6、模板消息接口封装
- 6.1、MessageController
- 6.2、service接口
- 6.3、service接口实现
- 6.4、通过swagger测试效果
- 三、微信授权登录
- 1、需求描述
- 2、授权登录
- 2.1、配置授权回调域名
- 2.2、部署公众号前端页面
- 2.3、前端处理
- 3、授权登录接口
- 3.1、引入微信工具包
- 3.2、添加配置
- 3.3、添加工具类
- 3.4、controller类
- 3.5、编写UserInfoService
- 3.6、使用token
- 3.6.1、JWT介绍
- 3.6.2、JWT的原理
- 3.6.3、整合JWT
一、公众号普通消息
1、实现目标
1、“硅谷课堂”公众号实现根据关键字搜索相关课程,如:输入“java”,可返回java相关的一个课程;
2、“硅谷课堂”公众号点击菜单“关于我们”,返回关于我们的介绍
3、关注或取消关注等
2、消息接入
参考文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
接入微信公众平台开发,开发者需要按照如下步骤完成:
1、填写服务器配置
2、验证服务器地址的有效性
3、依据接口文档实现业务逻辑
2.1、公众号服务器配置
在测试管理 -> 接口配置信息,点击“修改”按钮,填写服务器地址(URL)和Token,其中URL是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
说明:本地测试,url改为内网穿透地址
2.2、验证来自微信服务器消息
(1)概述
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1、将token、timestamp、nonce三个参数进行字典序排序
2、将三个参数字符串拼接成一个字符串进行sha1加密
3、开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
(2)代码实现
创建MessageController
@RestController
@RequestMapping("/api/wechat/message")
public class MessageController {private static final String token = "ggkt";/*** 服务器有效性验证* @param request* @return*/@GetMappingpublic String verifyToken(HttpServletRequest request) {String signature = request.getParameter("signature");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String echostr = request.getParameter("echostr");log.info("signature: {} nonce: {} echostr: {} timestamp: {}", signature, nonce, echostr, timestamp);if (this.checkSignature(signature, timestamp, nonce)) {log.info("token ok");return echostr;}return echostr;}private boolean checkSignature(String signature, String timestamp, String nonce) {String[] str = new String[]{token, timestamp, nonce};//排序Arrays.sort(str);//拼接字符串StringBuffer buffer = new StringBuffer();for (int i = 0; i < str.length; i++) {buffer.append(str[i]);}//进行sha1加密String temp = SHA1.encode(buffer.toString());//与微信提供的signature进行匹对return signature.equals(temp);}
}
OK,完成之后,我们的校验接口就算是开发完成了。接下来就可以开发消息接收接口了。
2.3、消息接收
接下来我们来开发消息接收接口,消息接收接口和上面的服务器校验接口地址是一样的,都是我们一开始在公众号后台配置的地址。只不过消息接收接口是一个 POST 请求。
在公众号后台配置的时候,消息加解密方式选择了明文模式,这样在后台收到的消息直接就可以处理了。微信服务器给我发来的普通文本消息格式如下:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId>
</xml>
参数 | 描述 |
---|---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 消息类型,文本为text |
Content | 文本消息内容 |
MsgId | 消息id,64位整型 |
看到这里,大家心里大概就有数了,当我们收到微信服务器发来的消息之后,我们就进行 XML 解析,提取出来我们需要的信息,去做相关的查询操作,再将查到的结果返回给微信服务器。
这里我们先来个简单的,我们将收到的消息解析并打印出来:
/*** 接收微信服务器发送来的消息* @param request* @return* @throws Exception*/@PostMappingpublic String receiveMessage(HttpServletRequest request) throws Exception {WxMpXmlMessage wxMpXmlMessage = WxMpXmlMessage.fromXml(request.getInputStream());System.out.println(JSONObject.toJSONString(wxMpXmlMessage));return "success";}private Map<String, String> parseXml(HttpServletRequest request) throws Exception {Map<String, String> map = new HashMap<String, String>();InputStream inputStream = request.getInputStream();SAXReader reader = new SAXReader();Document document = reader.read(inputStream);Element root = document.getRootElement();List<Element> elementList = root.elements();for (Element e : elementList) {map.put(e.getName(), e.getText());}inputStream.close();inputStream = null;return map;}
3、配置内网穿透(ngrok)
3.1、注册用户
网址:https://ngrok.cc/login/register
3.2、实名认证
(1)注册成功之后,登录系统,进行实名认证,认证费2元,认证通过后才能开通隧道
3.3、开通隧道
(1)选择隧道管理 -> 开通隧道
最后一个是免费服务器,建议选择付费服务器,10元/月,因为免费服务器使用人数很多,经常掉线
(2)点击立即购买 -> 输入相关信息
(3)开通成功后,查看开通的隧道
这里开通了两个隧道,一个用于后端接口调用,一个用于公众号前端调用
3.4、启动隧道
(1)下载客户端工具
(2)选择windows版本
(3)解压,找到bat文件,双击启动
(4)输入隧道id,多个使用逗号隔开,最后回车就可以启动
3.5、测试
启动服务,在硅谷课堂公众号发送文本消息测试效果。
4、消息业务实现
4.1、service_vod模块创建接口
(1)创建CourseApiController方法,根据课程关键字查询课程信息
@ApiOperation("根据关键字查询课程")@GetMapping("inner/findByKeyword/{keyword}")public List<Course> findByKeyword(@ApiParam(value = "关键字", required = true)@PathVariable String keyword){QueryWrapper<Course> queryWrapper = new QueryWrapper();queryWrapper.like("title", keyword);List<Course> list = courseService.list(queryWrapper);return list;}
4.2、创建模块定义接口
(1)service_client下创建子模块service_course_client
(2)定义根据关键字查询课程接口
@FeignClient(value = "service-vod")
public interface CourseFeignClient {@ApiOperation("根据关键字查询课程")@GetMapping("/api/vod/course/inner/findByKeyword/{keyword}")List<Course> findByKeyword(@PathVariable String keyword);
}
4.3、service_wechat引入依赖
<dependency><groupId>com.atguigu</groupId><artifactId>service_course_client</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
4.4、service_wechat模块实现方法
(1)MessageService
public interface MessageService {//接收消息String receiveMessage(Map<String, String> param);
}
(2)MessageServiceImpl
@Service
public class MessageServiceImpl implements MessageService {@Autowiredprivate CourseFeignClient courseFeignClient;@Autowiredprivate WxMpService wxMpService;//接收消息@Overridepublic String receiveMessage(Map<String, String> param) {String content = "";try {String msgType = param.get("MsgType");switch(msgType){case "text" :content = this.search(param);break;case "event" :String event = param.get("Event");String eventKey = param.get("EventKey");if("subscribe".equals(event)) {//关注公众号content = this.subscribe(param);} else if("unsubscribe".equals(event)) {//取消关注公众号content = this.unsubscribe(param);} else if("CLICK".equals(event) && "aboutUs".equals(eventKey)){content = this.aboutUs(param);} else {content = "success";}break;default:content = "success";}} catch (Exception e) {e.printStackTrace();content = this.text(param, "请重新输入关键字,没有匹配到相关视频课程").toString();}return content;}/*** 关于我们* @param param* @return*/private String aboutUs(Map<String, String> param) {return this.text(param, "硅谷课堂现开设Java、HTML5前端+全栈、大数据、全链路UI/UE设计、人工智能、大数据运维+Python自动化、Android+HTML5混合开发等多门课程;同时,通过视频分享、谷粒学苑在线课堂、大厂学苑直播课堂等多种方式,满足了全国编程爱好者对多样化学习场景的需求,已经为行业输送了大量IT技术人才。").toString();}/*** 处理关注事件* @param param* @return*/private String subscribe(Map<String, String> param) {//处理业务return this.text(param, "感谢你关注“硅谷课堂”,可以根据关键字搜索您想看的视频教程,如:JAVA基础、Spring boot、大数据等").toString();}/*** 处理取消关注事件* @param param* @return*/private String unsubscribe(Map<String, String> param) {//处理业务return "success";}/*** 处理关键字搜索事件* 图文消息个数;当用户发送文本、图片、语音、视频、图文、地理位置这六种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息* @param param* @return*/private String search(Map<String, String> param) {String fromusername = param.get("FromUserName");String tousername = param.get("ToUserName");String content = param.get("Content");//单位为秒,不是毫秒Long createTime = new Date().getTime() / 1000;StringBuffer text = new StringBuffer();List<Course> courseList = courseFeignClient.findByKeyword(content);if(CollectionUtils.isEmpty(courseList)) {text = this.text(param, "请重新输入关键字,没有匹配到相关视频课程");} else {//一次只能返回一个Random random = new Random();int num = random.nextInt(courseList.size());Course course = courseList.get(num);StringBuffer articles = new StringBuffer();articles.append("<item>");articles.append("<Title><![CDATA["+course.getTitle()+"]]></Title>");articles.append("<Description><![CDATA["+course.getTitle()+"]]></Description>");articles.append("<PicUrl><![CDATA["+course.getCover()+"]]></PicUrl>");articles.append("<Url><![CDATA[http://glkt.atguigu.cn/#/liveInfo/"+course.getId()+"]]></Url>");articles.append("</item>");text.append("<xml>");text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");text.append("<MsgType><![CDATA[news]]></MsgType>");text.append("<ArticleCount><![CDATA[1]]></ArticleCount>");text.append("<Articles>");text.append(articles);text.append("</Articles>");text.append("</xml>");}return text.toString();}/*** 回复文本* @param param* @param content* @return*/private StringBuffer text(Map<String, String> param, String content) {String fromusername = param.get("FromUserName");String tousername = param.get("ToUserName");//单位为秒,不是毫秒Long createTime = new Date().getTime() / 1000;StringBuffer text = new StringBuffer();text.append("<xml>");text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");text.append("<MsgType><![CDATA[text]]></MsgType>");text.append("<Content><![CDATA["+content+"]]></Content>");text.append("</xml>");return text;}
}
4.5、更改MessageController方法
/*** 接收微信服务器发送来的消息* @param request* @return* @throws Exception*/
@PostMapping
public String receiveMessage(HttpServletRequest request) throws Exception {Map<String, String> param = this.parseXml(request);return messageService.receiveMessage(param);
}
5、测试公众号消息
(1)点击个人 -> 关于我们,返回关于我们的介绍
(2)在公众号输入关键字,返回搜索的课程信息
二、公众号模板消息
1、实现目标
购买课程支付成功微信推送消息
2、模板消息实现
接口文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
3、申请模板消息
首先我们需要知道,模板消息是需要申请的。
但是我们在申请时还是有一些东西要注意,这个在官方的文档有非常详细的说明。
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Operation_Specifications.html
这个大家好好看看。选择行业的时候可要谨慎些,因为这个一个月只可以修改一次。
下面看看在哪里申请,硅谷课堂已经申请过,忽略
申请之后就耐心等待,审核通过之后就会出现“广告与服务”模板消息的菜单。
4、添加模板消息
审核通过之后,我们就可以添加模板消息,进行开发了。
我们点击模板消息进入后,直接在模板库中选择你需要的消息模板添加就可以了,添加之后就会在我的模板中。会有一个模板id,这个模板id在我们发送消息的时候会用到。
模板消息如下:
我们需要模板消息:
1、订单支付成功通知;
模板库中没有的模板,可以自定义模板,审核通过后可以使用。
5、公众号测试号申请模板消息
5.1、新增测试模板
5.2、填写信息
(1)下载示例参考
下载地址:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Operation_Specifications.html
(2)填写模板标题和模板内容
6、模板消息接口封装
6.1、MessageController
添加方法
@GetMapping("/pushPayMessage")
public Result pushPayMessage() throws WxErrorException {messageService.pushPayMessage(1L);return Result.ok();
}
6.2、service接口
MessageService
void pushPayMessage(Long orderId);
6.3、service接口实现
(1)MessageServiceImpl类
(2)openid值
(3)模板id值
@Autowired
private WxMpService wxMpService;//TODO 暂时写成固定值测试,后续完善
@SneakyThrows
@Override
public void pushPayMessage(long orderId) {String openid = "oepf36SawvvS8Rdqva-Cy4flFFtg";WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().toUser(openid)//要推送的用户openid.templateId("V-x2o4oTIW4rXwGzyM-YprNBQV9XmKxwpk_rQpXeGCE")//模板id.url("http://ggkt2.vipgz1.91tunnel.com/#/pay/"+orderId)//点击模板消息要访问的网址.build();//3,如果是正式版发送消息,,这里需要配置你的信息templateMessage.addData(new WxMpTemplateData("first", "亲爱的用户:您有一笔订单支付成功。", "#272727"));templateMessage.addData(new WxMpTemplateData("keyword1", "1314520", "#272727"));templateMessage.addData(new WxMpTemplateData("keyword2", "java基础课程", "#272727"));templateMessage.addData(new WxMpTemplateData("keyword3", "2022-01-11", "#272727"));templateMessage.addData(new WxMpTemplateData("keyword4", "100", "#272727"));templateMessage.addData(new WxMpTemplateData("remark", "感谢你购买课程,如有疑问,随时咨询!", "#272727"));String msg = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);System.out.println(msg);
}
6.4、通过swagger测试效果
(1)在公众号可以看到发送的模板消息
三、微信授权登录
1、需求描述
根据流程图通过菜单进入的页面都要授权登录
2、授权登录
接口文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
说明:
1、严格按照接口文档实现;
2、应用授权作用域scope:scope为snsapi_userinfo
2.1、配置授权回调域名
(1)在公众号正式号配置
在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“设置与开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;
本地测试配置内网穿透地址
(2)在公众号测试号配置
2.2、部署公众号前端页面
(1)公众号前端页面已经开发完成,直接部署使用即可
(2)启动公众号页面项目
使用命令:npm run serve
2.3、前端处理
(1)全局处理授权登录,处理页面:/src/App.vue
说明1:访问页面时首先判断是否有token信息,如果没有跳转到授权登录接口
说明2:通过localStorage存储token信息
在HTML5中,加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间很小,只有几K),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。它只能存储字符串格式的数据,所以最好在每次存储时把数据转换成json格式,取出的时候再转换回来。
(2)前端代码实现
wechatLogin() {// 处理微信授权登录let token = this.getQueryString('token') || '';if(token != '') {window.localStorage.setItem('token', token);}// 所有页面都必须登录,两次调整登录,这里与接口返回208状态token = window.localStorage.getItem('token') || '';if (token == '') {let url = window.location.href.replace('#', 'guiguketan')window.location = 'http://glkt.atguigu.cn/api/user/wechat/authorize?returnUrl=' + url}console.log('token2:'+window.localStorage.getItem('token'));},
3、授权登录接口
操作模块:service-user
3.1、引入微信工具包
<dependencies><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>2.7.0</version></dependency><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.1</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId></dependency>
</dependencies>
3.2、添加配置
#公众号id和秘钥
# 硅谷课堂微信公众平台appId
wechat.mpAppId: wx09f201e9013e81d8
## 硅谷课堂微信公众平台api秘钥
wechat.mpAppSecret: 6c999765c12c51850d28055e8b6e2eda
# 授权回调获取用户信息接口地址
wechat.userInfoUrl: http://ggkt.vipgz1.91tunnel.com/api/user/wechat/userInfo
3.3、添加工具类
@Component
public class ConstantPropertiesUtil implements InitializingBean {@Value("${wechat.mpAppId}")private String appid;@Value("${wechat.mpAppSecret}")private String appsecret;public static String ACCESS_KEY_ID;public static String ACCESS_KEY_SECRET;@Overridepublic void afterPropertiesSet() throws Exception {ACCESS_KEY_ID = appid;ACCESS_KEY_SECRET = appsecret;}
}
@Component
public class WeChatMpConfig {@Autowiredprivate ConstantPropertiesUtil constantPropertiesUtil;@Beanpublic WxMpService wxMpService(){WxMpService wxMpService = new WxMpServiceImpl();wxMpService.setWxMpConfigStorage(wxMpConfigStorage());return wxMpService;}@Beanpublic WxMpConfigStorage wxMpConfigStorage(){WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();wxMpConfigStorage.setAppId(ConstantPropertiesUtil.ACCESS_KEY_ID);wxMpConfigStorage.setSecret(ConstantPropertiesUtil.ACCESS_KEY_SECRET);return wxMpConfigStorage;}
}
3.4、controller类
@Controller
@RequestMapping("/api/user/wechat")
public class WechatController {@Autowiredprivate UserInfoService userInfoService;@Autowiredprivate WxMpService wxMpService;@Value("${wechat.userInfoUrl}")private String userInfoUrl;@GetMapping("/authorize")public String authorize(@RequestParam("returnUrl") String returnUrl, HttpServletRequest request) {String redirectURL = wxMpService.oauth2buildAuthorizationUrl(userInfoUrl, WxConsts.OAUTH2_SCOPE_USER_INFO, URLEncoder.encode(returnUrl.replace("guiguketan", "#")));return "redirect:" + redirectURL;}@GetMapping("/userInfo")public String userInfo(@RequestParam("code") String code,@RequestParam("state") String returnUrl) throws Exception {WxMpOAuth2AccessToken wxMpOAuth2AccessToken = this.wxMpService.oauth2getAccessToken(code);String openId = wxMpOAuth2AccessToken.getOpenId();System.out.println("【微信网页授权】openId={}"+openId);WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);System.out.println("【微信网页授权】wxMpUser={}"+JSON.toJSONString(wxMpUser));UserInfo userInfo = userInfoService.getByOpenid(openId);if(null == userInfo) {userInfo = new UserInfo();userInfo.setOpenId(openId);userInfo.setUnionId(wxMpUser.getUnionId());userInfo.setNickName(wxMpUser.getNickname());userInfo.setAvatar(wxMpUser.getHeadImgUrl());userInfo.setSex(wxMpUser.getSexId());userInfo.setProvince(wxMpUser.getProvince());userInfoService.save(userInfo);}//生成tokenString token = JwtHelper.createToken(userInfo.getId(), userInfo.getNickName());if(returnUrl.indexOf("?") == -1) {return "redirect:" + returnUrl + "?token=" + token;} else {return "redirect:" + returnUrl + "&token=" + token;}}
}
3.5、编写UserInfoService
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {@Overridepublic UserInfo getByOpenid(String openId) {QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();wrapper.eq("open_id",openId);UserInfo userInfo = baseMapper.selectOne(wrapper);return userInfo;}
}
3.6、使用token
通过token传递用户信息
3.6.1、JWT介绍
JWT工具
JWT(Json Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上
JWT最重要的作用就是对 token信息的防伪作用。
3.6.2、JWT的原理
一个JWT由三个部分组成:公共部分、私有部分、签名部分。最后由这三者组合进行base64编码得到JWT。
(1)公共部分
主要是该JWT的相关配置参数,比如签名的加密算法、格式类型、过期时间等等。
(2)私有部分
用户自定义的内容,根据实际需要真正要封装的信息。
userInfo{用户的Id,用户的昵称nickName}
(3)签名部分
SaltiP: 当前服务器的Ip地址!{linux 中配置代理服务器的ip}
主要用户对JWT生成字符串的时候,进行加密{盐值}
base64编码,并不是加密,只是把明文信息变成了不可见的字符串。但是其实只要用一些工具就可以把base64编码解成明文,所以不要在JWT中放入涉及私密的信息。
3.6.3、整合JWT
(1)在service_utils模块添加依赖
<dependencies><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency>
</dependencies>
(2)添加JWT工具类
public class JwtHelper {//token字符串有效时间private static long tokenExpiration = 24*60*60*1000;//加密编码秘钥private static String tokenSignKey = "123456";//根据userid 和 username 生成token字符串public static String createToken(Long userId, String userName) {String token = Jwts.builder()//设置token分类.setSubject("GGKT-USER")//token字符串有效时长.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))//私有部分(用户信息).claim("userId", userId).claim("userName", userName)//根据秘钥使用加密编码方式进行加密,对字符串压缩.signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}//从token字符串获取useridpublic static Long getUserId(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();Integer userId = (Integer)claims.get("userId");return userId.longValue();}//从token字符串获取getUserNamepublic static String getUserName(String token) {if(StringUtils.isEmpty(token)) return "";Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String)claims.get("userName");}public static void main(String[] args) {String token = JwtHelper.createToken(1L, "lucy");System.out.println(token);System.out.println(JwtHelper.getUserId(token));System.out.println(JwtHelper.getUserName(token));}
}
硅谷课堂 12_公众号消息和微信授权登录相关推荐
- 硅谷课堂第十一课-公众号消息和微信授权
硅谷课堂第十二天-公众号消息和微信授权登录 文章目录 硅谷课堂第十二天-公众号消息和微信授权登录 一.公众号普通消息 1.实现目标 2.消息接入 2.1.公众号服务器配置 2.2.验证来自微信服务器消 ...
- 60-硅谷课堂6-硅谷课堂-公众号消息和微信授权-- 笔记
60-硅谷课堂6-硅谷课堂-公众号消息和微信授权-- 笔记 笔记内容来源与尚硅谷教学视频 文章目录 60-硅谷课堂6-硅谷课堂-公众号消息和微信授权-- 笔记 笔记中涉及资源: 一.公众号普通消息 ① ...
- 微信公众号网页OAuth2.0授权登录并获取用户信息(SpringBoot实现)
微信公众号网页OAuth2.0授权登录并获取用户信息(SpringBoot实现) 文章目录 微信公众号网页OAuth2.0授权登录并获取用户信息(SpringBoot实现) 准备工作 开发思路 具体代 ...
- 微信公众号开发1-微信授权登录
说在前面的话 关于微信公众号的项目也已经告落一段时间了,但是项目结束后又有参加了新的项目,导致一直没有时间分享项目经验,今天正好得空来分享一下本项目,本项目主要用到了微信公众号开发,百度地图api等, ...
- 微信公众号前后端分离授权登录
前后端分离模式下微信授权登录 https://blog.csdn.net/qq_39524670/article/details/81118721?utm_medium=distribute.pc_r ...
- 微信公众号(H5)授权登录
拿到临时code 获取临时CODE网址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri ...
- 微信测试号申请以及微信授权登录
一.申请微信测试号 进入网址:微信测试号登录 接下来微信登录,然后进入页面 ① 第一点就是接口配置信息,可以使用springmvc或servlet来进行验证,我这里使用springmvc来编写验证代码 ...
- java 微信群发多图文_[Java教程]httpClient实现微信公众号消息群发
[Java教程]httpClient实现微信公众号消息群发 0 2016-09-21 20:00:10 1.实现功能 向关注了微信公众号的微信用户群发消息.(可以是所有的用户,也可以是提供了微信ope ...
- 专属微信公众号消息推送(java版)
前言:专属女朋友的微信推送消息,简单的写个文档. gitee地址:消息推送 所用框架及Api springboot搭建应用 天行数据Api(彩虹屁.早安语句.天气) 前置条件 申请微信公众号测试号及微 ...
最新文章
- 被马斯克送上天的《银河帝国》和互联网江湖 | 赠书
- web 中防止sql注入
- linux通过进程名查找进程,Linux下通过进程名获得进程号
- Android 网络交互之MD5为什么要加盐
- SAP UI5应用debug级别的日志打印如何设置
- 牛客练习赛75 D 减数游戏(队列优化(需要取模的)堆)
- 300张小抄表搞定机器学习知识点:学习根本停不下来!
- 表达式括号匹配(信息学奥赛一本通-T1353)
- 使用PowerShell读取文件数据
- 生成发布包_制作R包指南
- 基于ArcGIS和fragstats软件计算景观破碎度(二)
- python turtle库下载_turtle库安装
- 00003__位图简介
- 阿帕奇apache服务器和webDav服务器快速配置。
- 什么是HikariCP?HikariCP介绍(包含配置示例)
- WebStorm之如何清除缓存
- 计算机英语听力,每日英语听力pc版
- C++入门——Day5_分支语句和逻辑运算符
- 瓦片地图 cocos
- 学Linux有哪些就业方向?