微信授权官方文档
登录流程时序:
这里我是用微信开发者工具写的前端
login.wxml代码:
<view class="userinfo">
<block wx:if="{{!hasUserInfo}}">
<button class="addphoto_footer" wx:if="{{currentIndex == 0}}" bindtap="getUserProfile"> 获取头像昵称 </button>
<button class="addphoto_footer" wx:if="{{currentIndex == 1}}" bindtap="getUserInfo"> 获取头像昵称 </button>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
login.js:
getUserProfile: function (e) {
var that = this;
wx.getUserProfile({
desc: '必须授权才能使用',
success: res => {
let user = res.userInfo
this.setData({
user: user,
encryptedData: res.encryptedData,
iv: res.iv
})
var encryptedData = res.encryptedData;
var iv = res.iv;
wx.login({
success: (res) => {
if (res.code) {
wx.request({
url: '请求地址',
method: 'Get',
header: {
'content-type': 'application/x-www-form-urlencoded',
},
data: {
code: res.code,
encryptedData: encryptedData,
iv: iv,
},
success(res) {
console.log("success!!!")
}
})
}
}
})
},
fall: res => {
console.log('失败', res)
},
后端代码:
WxCtrl:
private WxService wxService;
@Autowired
@Resource
private RestTemplate restTemplate;
String AppId = "***********"; //公众平台自己的appId
String AppSecret = "****************"; //AppSecret
@GetMapping("/login")
public Map<String, Object> wxDoLogin(@RequestParam("code") String code, String encryptedData, String iv) throws Exception {
Map<String, Object> result = new HashMap<>();
System.out.println("code is " + code);
String access_token = String.valueOf(AccessToken.getAccessToken());
result.put("status", 200);
String url = "https://api.weixin.qq.com/sns/jscode2session?" +
"appid=" + AppId +
"&secret=" + AppSecret +
"&js_code=" + code +
"&grant_type=authorization_code";
String jsonData = restTemplate.getForObject(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(jsonData);
if (StringUtils.contains(jsonData, "errcode")) {
result.put("status", 500);
result.put("msg", "登录失败");
}
String openid = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
//解密
// String s = wxService.wxDecrypt(encryptedData, jsonObject, iv);
// JSONObject jsonObject1 = JSON.parseObject(s);
// Object watermark = jsonObject1.get("watermark");
// JSONObject jsonObject2 = JSON.parseObject(String.valueOf(watermark));
return result;
}
WxService
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.codec.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Random;
@Slf4j
@Component
public class WxService {
public String wxDecrypt(String encryptedData, JSONObject jsonObject, String vi) throws Exception {
// 开始解密
String sessionKey = (String) jsonObject.get("session_key");
byte[] encData = cn.hutool.core.codec.Base64.decode(encryptedData);
byte[] iv = cn.hutool.core.codec.Base64.decode(vi);
byte[] key = Base64.decode(sessionKey);
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(cipher.doFinal(encData), "UTF-8");
}
//生成随机用户名,数字和字母组成,
public String getStringRandom(int length) {
StringBuilder val = new StringBuilder();
Random random = new Random();
//参数length,表示生成几位随机数
for (int i = 0; i < length; i++) {
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
//输出字母还是数字
if ("char".equalsIgnoreCase(charOrNum)) {
//输出是大写字母还是小写字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val.append((char) (random.nextInt(26) + temp));
} else {
val.append(random.nextInt(10));
}
}
return val.toString();
}
}
RestTemplateConfig
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}