mirror of
https://github.com/certd/certd.git
synced 2026-05-16 05:07:32 +08:00
134 lines
3.6 KiB
TypeScript
134 lines
3.6 KiB
TypeScript
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server";
|
|
import { BuildLoginUrlReq, BuildLogoutUrlReq, IOauthProvider, OnCallbackReq } from "../api.js";
|
|
|
|
@IsAddon({
|
|
addonType: "oauth",
|
|
name: 'wx',
|
|
title: '微信登录',
|
|
desc: '微信网站应用登录',
|
|
icon: "mdi:wechat",
|
|
showTest: false,
|
|
})
|
|
export class WxOauthProvider extends BaseAddon implements IOauthProvider {
|
|
|
|
@AddonInput({
|
|
title: "AppId",
|
|
required: true,
|
|
helper: "在[微信开放平台](https://open.weixin.qq.com/cgi-bin/index)注册网站应用后获取",
|
|
})
|
|
appId = "";
|
|
|
|
@AddonInput({
|
|
title: "AppSecretKey",
|
|
component: {
|
|
placeholder: "AppSecretKey",
|
|
},
|
|
required: true,
|
|
})
|
|
appSecretKey = "";
|
|
|
|
|
|
wxAccessToken?: { access_token: string, expires_at: number }
|
|
|
|
async buildLoginUrl(params: BuildLoginUrlReq) {
|
|
|
|
const from = params.from || "web";
|
|
const appId = this.appId;
|
|
const redirect_uri = encodeURIComponent(params.redirectUri);
|
|
let state: any = {
|
|
forType: params.forType,
|
|
from
|
|
}
|
|
state = this.ctx.utils.hash.base64(JSON.stringify(state))
|
|
let scope = "snsapi_userinfo";
|
|
let loginUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`
|
|
if (from === "web") {
|
|
scope = "snsapi_login";
|
|
loginUrl = `https://open.weixin.qq.com/connect/qrconnect?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`
|
|
}
|
|
|
|
return {
|
|
loginUrl,
|
|
ticketValue: {
|
|
state,
|
|
},
|
|
};
|
|
}
|
|
|
|
// async getWxAccessToken() {
|
|
// if (this.wxAccessToken && this.wxAccessToken.expires_at > Date.now()) {
|
|
// return this.wxAccessToken
|
|
// }
|
|
// const res = await this.http.request({
|
|
// url: "https://api.weixin.qq.com/cgi-bin/token",
|
|
// method: "GET",
|
|
// params: {
|
|
// appid: this.appId,
|
|
// secret: this.appSecretKey,
|
|
// grant_type: "client_credential",
|
|
// },
|
|
// })
|
|
// this.checkRet(res)
|
|
// this.wxAccessToken = {
|
|
// access_token: res.access_token,
|
|
// expires_at: Date.now() + res.expires_in * 1000,
|
|
// }
|
|
// return this.wxAccessToken
|
|
// }
|
|
|
|
checkRet(res: any) {
|
|
if (res.errcode) {
|
|
throw new Error(res.errmsg)
|
|
}
|
|
}
|
|
|
|
async onCallback(req: OnCallbackReq) {
|
|
|
|
|
|
// GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx520c15f417810387&secret=SECRET&code=CODE&grant_type=authorization_code
|
|
const res = await this.http.request({
|
|
url: "https://api.weixin.qq.com/sns/oauth2/access_token",
|
|
method: "GET",
|
|
params: {
|
|
appid: this.appId,
|
|
secret: this.appSecretKey,
|
|
code: req.code,
|
|
grant_type: "authorization_code",
|
|
},
|
|
})
|
|
this.checkRet(res)
|
|
const accessToken = res.access_token
|
|
|
|
|
|
// GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
|
|
const userInfoRes = await this.http.request({
|
|
url: "https://api.weixin.qq.com/sns/userinfo",
|
|
method: "GET",
|
|
params: {
|
|
access_token:accessToken,
|
|
openid: res.openid,
|
|
lang: "zh_CN",
|
|
},
|
|
})
|
|
this.checkRet(userInfoRes)
|
|
|
|
return {
|
|
token: {
|
|
accessToken: res.access_token,
|
|
refreshToken: res.refresh_token,
|
|
expiresIn: res.expires_in,
|
|
},
|
|
userInfo: {
|
|
openId: res.unionid || res.openid,
|
|
nickName: userInfoRes.nickname || "",
|
|
avatar: userInfoRes.headimgurl,
|
|
},
|
|
}
|
|
};
|
|
|
|
|
|
async buildLogoutUrl(params: BuildLogoutUrlReq) {
|
|
return {};
|
|
}
|
|
}
|