A detailed explanation of the official login flow chart;
After creating a wechat applet project, we can see that the app.js file provides a reference case of login function, based on which we make some improvements;
- 1. First of all, I changed the Wx. login to handle it in the way of promise. The Wx. login API was used to obtain the code value, and then our backend server made an interface to receive the user’s code value (THE API backend server here was implemented by Golang technology. Attach the interface code)
Login / / promiselet self = this;
const userLogin = new Promise(function(resolve, reject) { wx.login({ success: OpenId, sessionKey, unionId webhttp. get(api.usercode. opendId, {code: res.code}) .then((res) => { resolve(); }).catch( err => { reject(err); })}})})Copy the code
- 2. In the last step, we obtained the usercode, appID and secret information of the small program from the front end to the sender server, and the server side obtained the openID, session_key and unionID information of the user through the wechat interface through these data (the following is the implementation method of golang back-end).
package v1
import (
"encoding/json"
"io/ioutil"
"net/http"
"miniprogram_api/models"
"miniprogram_api/pkg/e"
"strings"
"github.com/gin-gonic/gin"Var WxUserInfo map[string]interface{} Get userCode, openid, session_key func GetOpenid(c *gin.Context) {// get wechat user login zero time code, small program code, key userCode := c.query ("code")
appid := "* * * * * * * *"
secret := "* * * * * * * * * * * * * *"
code := e.SUCCESS
ifuserCode ! =""{// Get user openID session_key result, _ := SendCodeToWx(userCode, appID, secret) WxUserInfo = result c.JSON(http.StatusOK, gin.H{"code": code,
"msg": e.GetMsg(code),
})
return
}
code = e.ERROR_GET_CODE
c.JSON(http.StatusOK, gin.H{
"code": code,
"msg": e.GetMsg(code),
"data": make(map[string]interface{}), }) } func SendCodeToWx(code, appid, AppSecret string) (map[string]interface{}, Error) {// Request address concatenation URL :="https://api.weixin.qq.com/sns/jscode2session?js_code=" + code + "&appid=" + appid + "&secret=" + AppSecret + "&grant_type=authorization_code"Client := &http. client {} result := make(map[string]interface{}) // get request for openID req, err := http.NewRequest("GET", url, strings.NewReader("name=cjb"))
iferr ! = nil {return result, err
}
resp, err := client.Do(req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
iferr ! = nil {return result, err
}
json.Unmarshal(body, &result)
return result, err
}
Copy the code
The api.weixin.qq.com/sns/jscode2… This is the openID access interface provided by wechat. The following figure shows the detailed information of the interface provided by wechat
- 3. After the application is completed, we can use JWT to authenticate user login token at the backend. For the moment, I have not added token to control the access permission through API (JWT on the server side has not been written yet, and it will be added later).
4. The fourth step is to obtain the nickname, avater, region and other information of the login account through wx.getUserInfo, and then to obtain the information we can store it in our own user table. The following is the user data request made by wechat and the interface made by the server to store the information
Complete app.js implementation
// This is wechat request encapsulation import webHttp from'./utils/request'; // API location agrees to manage import API from'./utils/apiconfig';
//app.js
App({
onLaunch: function// var logs = wx.getStoragesync () {// var logs = wx.getStoragesync ();'logs') || []
// logs.unshift(Date.now())
// wx.setStorageSync('logs'// Log in to promiselet self = this;
const userLogin = new Promise(function(resolve, reject) { wx.login({ success: OpenId, sessionKey, unionId webhttp. get(api.usercode. opendId, {code: res.code}) .then((res) => { resolve(); }).catch( err => { reject(err); })}) const getSetting = new Promise(function (resolve, reject) {
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo'Wx. getUserInfo({success:}) {wx.getUserInfo({success:}); Res => {// The res can be sent to the background to decode unionId self.globaldata.userInfo = res.userInfo // Since getUserInfo is a network request, It is possible to return // after page.onload, so callback is added here to prevent thisif(self.userInfoReadyCallback) { self.userInfoReadyCallback(res) } resolve(); }})}}}); }) Promise.all([userLogin, GetSetting]).then((res) => {userInfoSet()}).catch((err) => {console.log(err)}) // The user data store databasefunction userInfoSet() { webHttp.get(api.user.info, { ... self.globalData.userInfo }).then((res) => { console.log(res); }) } }, globalData: { userInfo: null, } })Copy the code
Below is the golang database table structure design and storage
package models
import (
"time"
"github.com/jinzhu/gorm"
)
type User struct {
Model
CreatedBy string `json:"created_by"`
ModifiedBy string `json:"modified_by"`
Opendid string `json:"opendid"`
NickName string `json:"nick_name"`
AvaterUrl string `json:"avater_url"`
Gender string `json:"gender"Func Login(openID String) (bool, User) {var User User db.Where("openid=?", openid).First(&user)
if user.ID > 0 {
return true, user
}
return falseFunc EditInfo(openDid String, data interface{}) bool {db.model (&user {}).Where(openDid string, data interface{})"opendi = ?", opendid).Updates(data)
return trueFunc RegisterUserInfo(data map[string]interface{}) bool {db.Create(&User{Opendid: data["openid"].(string),
NickName: data["nick_name"].(string),
AvaterUrl:data["avater_url"].(string),
Gender: data["gender"].(string),
})
return true} // modify the adjustment timestamp func (article *User) BeforeCreate(scope * gorm.scope) error {scope.setcolumn (article *User)"CreatedOn", time.Now().Unix())
return nil
}
func (article *User) BeforeUpdate(scope *gorm.Scope) error {
scope.SetColumn("ModifiedOn", time.Now().Unix())
return nil
}
Copy the code
Understand process is such a process, this is the opening in the process of the whole stack cultivate immortality, also tried putting their self-study of something by yourself slowly combine to do a small program the demo project, at the same time small program was just to fit in the front end of the title Lord was a simple, hobby and livelihoods from begin to learn something, just comfort, Is there any misunderstanding, I hope you can give me some advice, progress is endless, and share with you ~