获取临时域名,配置公众号信息等参考:
微信公众号网页授权登录_m0_53611007的博客-CSDN博客
开启测试号网页授权功能并配置这一项可以不配置
不过扫码登录要配置的是:
如果微信服务器请求这个url时 自己在这里设置的token与接口不对应时无法配置成功的
这个接口代码如下:
@RequestMapping ("/checkSign")
public String checkSign ( HttpServletRequest request) throws Exception {
//获取微信请求参数
String signature = request.getParameter ("signature");
String timestamp = request.getParameter ("timestamp");
String nonce = request.getParameter ("nonce");
String echostr = request.getParameter ("echostr");
//参数排序。 token 就要换成自己实际写的 token
String [] params = new String [] {timestamp,nonce,"123456"} ;
Arrays.sort (params) ;
//拼接
String paramstr = params[0] + params[1] + params[2] ;
//加密
//获取 shal 算法封装类
MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;
//进行加密
byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));
//拿到加密结果
//String mysignature = WebUtils.byte2HexStr(digestResult);
String mysignature = FileDataConvert.bytes2HexString(digestResult);
mysignature=mysignature.toLowerCase(Locale.ROOT);
//是否正确
boolean signsuccess = mysignature.equals(signature);
//逻辑处理
if (signsuccess && echostr!=null) {
//peizhi token
return echostr ;//不正确就直接返回失败提示.
}else{
JSONObject jsonObject = callback(request);
return jsonObject.toJSONString();
}
}
@RequestMapping("callback")
public JSONObject callback(HttpServletRequest request) throws Exception{
//request中有相应的信息,进行解析
WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml
String messageType=message.getMsgType(); //消息类型
String messageEvent=message.getEvent(); //消息事件
// openid
String fromUser=message.getFromUser(); //发送者帐号
String touser=message.getToUser(); //开发者微信号
String text=message.getContent(); //文本消息 文本内容
// 生成二维码时穿过的特殊参数
String eventKey=message.getEventKey(); //二维码参数
String uuid=""; //从二维码参数中获取uuid通过该uuid可通过websocket前端传数据
String userid="";
//if判断,判断查询
JSONObject jsonObject = new JSONObject();
jsonObject.put("code","200");
if(messageType.equals("event")){
//先根据openid从数据库查询 => 从自己数据库中查取用户信息
jsonObject = null;
if(messageEvent.equals("SCAN")){
//扫描二维码
//return "欢迎回来";
}
if(messageEvent.equals("subscribe")){
//关注
//return "谢谢您的关注";
}
//没有该用户
if(jsonObject==null){
//从微信上中拉取用户信息
String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +
"&openid=" + fromUser +
"&lang=zh_CN";
String result = HttpClientUtil.doGet(url);
jsonObject = JSONObject.parseObject(result);
}
loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));
return jsonObject;
//return userInfo.toString();
}
return jsonObject;
//log.info("消息类型:{},消息事件:{},发送者账号:{},接收者微信:{},文本消息:{},二维码参数:{}",messageType,messageEvent,fromUser,touser,text,eventKey);
}
点击登录js
function codeAuthLogin() {
$.get("qcCodeLogin/getQrCode",
function(data,status){
console.log(data);
sceneStr = data.sceneStr;
$('#qrCodeId').attr('src',"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+data.ticket);
$('#qrCodeId').show();
t = window.setInterval(getOpenId,3000);
});
}
登录接口:
// 微信开放平台二维码连接
private final static String getQrCode= "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
private final static String getToken= "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
@Autowired
private WxConfig wxConfig;
@Autowired
private HttpSession httpSession;
// 模拟数据库存储或者缓存存储
Map<String,CodeLoginKey> loginMap = new HashMap<>();
@GetMapping("/getQrCode")
private JSONObject getQrCode(){
try {
// 获取token开发者
String accessToken =getAccessToken();
String getQrCodeUrl = getQrCode.replace("TOKEN", accessToken);
// 这里生成一个带参数的二维码,参数是scene_str
String sceneStr = getRandomString(8);
String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";
String result = HttpClientUtil.doPostJson(getQrCodeUrl,json);
JSONObject jsonObject = JSONObject.parseObject(result);
jsonObject.put("sceneStr",sceneStr);
return jsonObject;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
这时我们可以获取微信给的二维码扫描二维码请求接口js
function getOpenId() {
$.get("qcCodeLogin/getOpenId",{
"eventKey":sceneStr
},function (data) {
if(data.code == 200){
console.log("==================");
console.log(data.data);
window.clearInterval(t);
alert("登录成功:"+data.data.openId);
}
});
}
接口:
@RequestMapping("getOpenId")
public ResultJson getOpenId(String eventKey){
if(loginMap.get(eventKey) == null){
return ResultJson.failure(ResultCode.SERVER_ERROR,"未扫码成功!") ;
}
CodeLoginKey codeLoginKey = loginMap.get(eventKey);
loginMap.remove(eventKey);
return ResultJson.ok(codeLoginKey);
}
整体代码:
@RestController
@RequestMapping("qcCodeLogin")
public class QrCodeLoginController {
// 微信开放平台二维码连接
private final static String getQrCode= "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
private final static String getToken= "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
@Autowired
private WxConfig wxConfig;
@Autowired
private HttpSession httpSession;
// 模拟数据库存储或者缓存存储
Map<String,CodeLoginKey> loginMap = new HashMap<>();
@GetMapping("/getQrCode")
private JSONObject getQrCode(){
try {
// 获取token开发者
String accessToken =getAccessToken();
String getQrCodeUrl = getQrCode.replace("TOKEN", accessToken);
// 这里生成一个带参数的二维码,参数是scene_str
String sceneStr = getRandomString(8);
String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";
String result = HttpClientUtil.doPostJson(getQrCodeUrl,json);
JSONObject jsonObject = JSONObject.parseObject(result);
jsonObject.put("sceneStr",sceneStr);
return jsonObject;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//length用户要求产生字符串的长度
public static String getRandomString(int length){
String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random=new Random();
StringBuffer sb=new StringBuffer();
for(int i=0;i<length;i++){
int number=random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
public String getAccessToken(){
String accessToken = null;
if(httpSession.getAttribute("code_access_token") != null){
return httpSession.getAttribute("code_access_token").toString();
}
String getTokenUrl = getToken.replace("APPID", wxConfig.getAppId()).replace("SECRET", wxConfig.getAppSecret());
String result = HttpClientUtil.doGet(getTokenUrl);
JSONObject jsonObject = JSONObject.parseObject(result);
accessToken = jsonObject.getString("access_token");
httpSession.setAttribute("code_access_token",accessToken);
return accessToken ;
}
@RequestMapping ("/checkSign")
public String checkSign ( HttpServletRequest request) throws Exception {
//获取微信请求参数
String signature = request.getParameter ("signature");
String timestamp = request.getParameter ("timestamp");
String nonce = request.getParameter ("nonce");
String echostr = request.getParameter ("echostr");
//参数排序。 token 就要换成自己实际写的 token
String [] params = new String [] {timestamp,nonce,"123456"} ;
Arrays.sort (params) ;
//拼接
String paramstr = params[0] + params[1] + params[2] ;
//加密
//获取 shal 算法封装类
MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;
//进行加密
byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));
//拿到加密结果
//String mysignature = WebUtils.byte2HexStr(digestResult);
String mysignature = FileDataConvert.bytes2HexString(digestResult);
mysignature=mysignature.toLowerCase(Locale.ROOT);
//是否正确
boolean signsuccess = mysignature.equals(signature);
//逻辑处理
if (signsuccess && echostr!=null) {
//peizhi token
return echostr ;//不正确就直接返回失败提示.
}else{
JSONObject jsonObject = callback(request);
return jsonObject.toJSONString();
}
}
@RequestMapping("callback")
public JSONObject callback(HttpServletRequest request) throws Exception{
//request中有相应的信息,进行解析
WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml
String messageType=message.getMsgType(); //消息类型
String messageEvent=message.getEvent(); //消息事件
// openid
String fromUser=message.getFromUser(); //发送者帐号
String touser=message.getToUser(); //开发者微信号
String text=message.getContent(); //文本消息 文本内容
// 生成二维码时穿过的特殊参数
String eventKey=message.getEventKey(); //二维码参数
String uuid=""; //从二维码参数中获取uuid通过该uuid可通过websocket前端传数据
String userid="";
//if判断,判断查询
JSONObject jsonObject = new JSONObject();
jsonObject.put("code","200");
if(messageType.equals("event")){
//先根据openid从数据库查询 => 从自己数据库中查取用户信息
jsonObject = null;
if(messageEvent.equals("SCAN")){
//扫描二维码
//return "欢迎回来";
}
if(messageEvent.equals("subscribe")){
//关注
//return "谢谢您的关注";
}
//没有该用户
if(jsonObject==null){
//从微信上中拉取用户信息
String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +
"&openid=" + fromUser +
"&lang=zh_CN";
String result = HttpClientUtil.doGet(url);
jsonObject = JSONObject.parseObject(result);
}
loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));
return jsonObject;
//return userInfo.toString();
}
return jsonObject;
//log.info("消息类型:{},消息事件:{},发送者账号:{},接收者微信:{},文本消息:{},二维码参数:{}",messageType,messageEvent,fromUser,touser,text,eventKey);
}
@RequestMapping("getOpenId")
public ResultJson getOpenId(String eventKey){
if(loginMap.get(eventKey) == null){
return ResultJson.failure(ResultCode.SERVER_ERROR,"未扫码成功!") ;
}
CodeLoginKey codeLoginKey = loginMap.get(eventKey);
loginMap.remove(eventKey);
return ResultJson.ok(codeLoginKey);
}
}
登录成功后返回用户信息的一个工具类:
public class CodeLoginKey {
private String eventKey;
private String openId;
public CodeLoginKey(String eventKey, String openId) {
this.eventKey = eventKey;
this.openId = openId;
}
public String getEventKey() {
return eventKey;
}
public void setEventKey(String eventKey) {
this.eventKey = eventKey;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
@Override
public String toString() {
return "CodeLoginKey{" +
"eventKey='" + eventKey + '\'' +
", openId='" + openId + '\'' +
'}';
}
}