记录一下go语言微信小程序登录
我这边主要是已有账号跟微信账号去进行绑定的一个流程
思路:
1、小程序通过code调用接口获取token。
2、如果是第一次登录,那么通过入参已有账号、密码、code,通过第三方接口得到OpenId进行绑定并且返回token。
- golang端
//小程序登录传入的数据
type ConfirmLoginDto struct {
Iv string `json:"iv"`
WxCode string `json:"wx_code"`
Token string `json:"token"` //账号登录认证
Nickname string `json:"nickname"` //微信昵称
Headimage string `json:"headimage"` //微信头像
User string `json:"user"` //账号
Passwd string `json:"passwd"` //密码
}
//账号信息
type User struct {
这里自己去写
}
/*微信小程序登录 返回值*/
type WXLoginResp struct {
OpenId string `json:"openid"`
SessionKey string `json:"session_key"`
UnionId string `json:"unionid"`
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
Token string `json:"token"`
Auth uint32 `json:"auth"`
Name string `json:"name"`
Phone string `json:"phone"`
Nickname string `json:"nickname"` //微信昵称
Headimage string `json:"headimage"` //微信头像
}
func wxLoginHandler(ctx iris.Context) {
var user ConfirmLoginDto
var err error
// user.Token = ctx.GetHeader("token")
if err = ctx.ReadJSON(&user); err != nil {
ctx.StatusCode(iris.StatusBadRequest)
} else if user.WxCode == "" {
err = errors.New("code值不能为空")
}
if err != nil {
ctx.JSON(iris.Map{"result_code": 500, "result_msg": err.Error()})
return
}
users, err := wxLogin(&user)
if err == nil {
ctx.JSON(iris.Map{"result_code": 200, "result_msg": "success", "data": users})
} else {
ctx.JSON(iris.Map{"result_code": 500, "result_msg": err.Error()})
}
}
/*根据wx_code返回token ...*/
func wxLogin(user *ConfirmLoginDto) (*WXLoginResp, error) {
session := GetConnection()
defer session.Close()
url := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
// 合成url, 这里的appId和secret是在微信公众平台上获取的
url = fmt.Sprintf(url, "填你的appid", "填secret", user.WxCode)
// 创建http get请求
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// 解析http请求中body 数据到我们定义的结构体中
wxResp := WXLoginResp{}
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&wxResp); err != nil {
return nil, err
}
// 判断微信接口返回的是否是一个异常情况
if wxResp.ErrCode != 0 {
return nil, errors.New(fmt.Sprintf("ErrCode:%s ErrMsg:%s", wxResp.ErrCode, wxResp.ErrMsg))
}
var userInfo User
session, err := mgo.Dial("mongodb://账号:密码@ip:端口/名称") //要连接的服务器和端口
if err != nil {
panic(err)
}
c := session.DB("名称").C("user_info")
err = c.Find(bson.M{"open_id": wxResp.OpenId}).One(&userInfo)
if user.User != "" && user.Passwd != "" { //账号绑定微信,更新
err := c.Find(bson.M{"user": user.User}).One(&userInfo)
if err != nil {
return nil, errors.New("该账号不存在")
} else if userInfo.Passwd != user.Passwd {
return nil, errors.New("密码错误")
} else {
userInfo.Open_id = wxResp.OpenId
userInfo.Nickname = user.Nickname
userInfo.Headimage = user.Headimage
c.Update(bson.M{"token": userInfo.Token}, userInfo)
}
} else if err != nil {
return nil, errors.New("请先登录")
}
wxResp.Auth = userInfo.Auth
wxResp.Token = userInfo.Token
wxResp.Name = userInfo.Name
wxResp.Phone = userInfo.Phone
wxResp.Nickname = userInfo.Nickname
wxResp.Headimage = userInfo.Headimage
wxResp.OpenId = ""
wxResp.SessionKey = ""
return &wxResp, nil
}
- 小程序
config.js 用来存放公共数据
var config = {
token:"",
name:"",//账号昵称
auth:null,//账号权限 0:管理员 1:打工人
userInfo:null,//微信账号信息
}
module.exports = config;
app.js
// 登录
var http = require('./utils/request.js');
var config = require('./config');
wx.login({
success: res => {
// console.log('登陆login',res)
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var params = {//请求参数
wx_code: res.code,//用户登录凭证(有效期五分钟)
}
http.postRequest("user/wxlogin", params, res => {
console.log("code登录接口");
if(res.result_msg== "请先登录"){//第一次进入小程序,那么我们去登录页
// wx.reLaunch({
// url: '../../login/login'
// })
var pages = getCurrentPages() //获取加载的页面
var currentPage = pages[pages.length-1] //获取当前页面的对象
var url = currentPage.route //当前页面url
var skipUrl = ""
for(let I = 1; I < url.split("/").length-1; I++){
skipUrl = skipUrl + '../'
}
wx.reLaunch({
url: skipUrl+'login/login'
})
}else{
//存起来
config.name = res.data.name
config.auth = res.data.auth
config.token = res.data.token
config.userInfo = {
nickname:res.data.nickname,
headimage:res.data.headimage
}
}
console.log(res,config);
}, res => {
console.log("请求失败了傻瓜")
})
}
})
pages/login/login.js
var http = require('../../utils/request.js');
var config = require('../../config');
Page({
data() {
return {
username: '',
password: '',
};
},
onChange1(event) {
// event.detail 为当前输入的值
console.log(event.detail);
this.setData({ username: event.detail })
},
onChange2(event) {
// event.detail 为当前输入的值
console.log(event.detail);
this.setData({ password: event.detail })
},
login(){
if(config.userInfo){
this.postLogin()
}else{
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
console.log(res.userInfo)
let userInfo = res.userInfo
config.userInfo = userInfo
this.postLogin()
}
})
}
},
postLogin(){
wx.login({
success: res => {
// console.log('登陆login',res)
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var params = {//请求参数
wx_code: res.code,//用户登录凭证(有效期五分钟)
user:this.data.username,
passwd:this.data.password,
nickname:config.userInfo.nickName,
headimage:config.userInfo.avatarUrl
}
http.postRequest("user/wxlogin", params, res => {
console.log("登录接口");
console.log(res);
if(res.result_code == 200){
config.name = res.data.name
config.auth = res.data.auth
config.token = res.data.token
wx.reLaunch({
url: '../indexs/my'
})
}
}, res => {
console.log("请求登录失败了")
})
}
})
},
})
//附带一下login.wxml
<van-field
value="{{ username }}"
placeholder="请输入用户名"
border="{{ false }}"
bind:change="onChange1"
/>
<van-field
value="{{ password }}"
placeholder="请输入密码"
border="{{ false }}"
bind:change="onChange2"
/>
<van-button type="primary" bindtap="login">登录</van-button>
utils/request.js
var app = getApp(); //获取小程序全局唯一app实例
var config = require('../config');
// 非开发环境的服务器域名
let host = 'http://xiaohongdechuanr.com:8001/'; //接口地址
// platform 用来判断是否是开发环境
const {platform} = wx.getSystemInfoSync()
// 开发环境的服务器域名
if(platform === 'devtools'){
host = 'http://190.161.8.9:8001/';//小红的本地
}
//url:接口
//postData:参数
//doSuccess:成功的回调函数
//doFail:失败的回调函数
//POST请求
function post(url, postData, doSuccess, doFail) {
request(url, postData, "POST", doSuccess, doFail);
}
//GET请求
function get(url, postData, doSuccess, doFail) {
request(url, postData, "GET", doSuccess, doFail);
}
function request(url, postData, method, doSuccess, doFail) {
wx.showLoading({
title: "正在加载中...",
})
wx.request({
url: host + url, //请求地址
method: method, //请求方法
header: { //请求头
"Content-Type": "application/json;charset=UTF-8",
"token":config.token
},
data: postData, //请求参数
dataType: 'json', //返回数据格式
responseType: 'text', //响应的数据类型
success: function(res) {
// console.log(res)
wx.hideLoading();
if(res.data.result_code == 200){
//成功执行方法,参数值为res.data,直接将返回的数据传入
doSuccess(res.data);
}else{
wx.showToast({
title: res.data.result_msg,
icon:'error'
})
doSuccess(res.data);
}
},
fail: function() {
wx.hideLoading();
//失败执行方法
doFail();
},
})
}
//module.exports用来导出代码
//js文件中通过var http = require("../../util/request.js")加载
module.exports = {
postRequest: post,
getRequest: get,
}
// 使用实例
// var http = require('../../utils/request.js'); //相对路径
// var params = {//请求参数
// aid: this.optionaid, //id
// aname: this.data.receiving, //收货人
// atell: this.data.tell, //联系方式
// adetailed: this.data.detailed, //详细地址
// }
// http.postRequest("EditAddress/EditAddressInfo", params, function(res) {
// console.log("修改成功!");
// wx.navigateTo({
// url: '/pages/address/address',
// })
// }, function(res) {
// console.log("修改失败!!!")
// })