Before, I used a small program to do the project, and everything went well because OF the Java development used in the background. However, when I switched to Django to do RESTful API interface, THERE were problems when I logged in and registered. I searched online and found a feasible solution with the help of a user’s answer.

The specific process

  • The user clicks login authorization on the applet page
  • Obtain the code through the authentication provided by wechat
  • Call up the login interface and pass code into the background
  • The background gets the code and invokes the wechat interface to obtain user information such as OpenID
  • The background uses OpenID as the user name. If it exists, the user information is verified; otherwise, a new user is created with the user name, and the password is randomly generated
  • Return the verification result or creation information to the wechat applet end
  • Verify user login based on the returned information

Djangos user permission authentication

Django has a complete User model of its own. Since django Auth comes with a User model with limited fields, we need to extend it (or use it directly)

nickname = models.CharField(verbose_name=U 'nickname',max_length=50, blank=True)
user_avatar =  models.ImageField(verbose_name=U 'User profile picture', upload_to='image/%Y/%m/%d', default=u'image/default.png', max_length=500)
user_email = models.EmailField(verbose_name=U 'User's mailbox',max_length=254)
user_phone = models.BigIntegerField(verbose_name=U 'Mobile phone number', null=True,blank=True)
user_birthday = models.DateField(verbose_name=U 'Date of birth', default = timezone.now)
user_sex = models.CharField(verbose_name=U 'gender',max_length=6,choices=(('male'.'male'), ('female'.'woman')),default='male')
user_address = models.CharField(verbose_name=U 'address',max_length=550, blank=True,null=True)
signature = models.CharField(verbose_name=U 'Personal signature',max_length=550, blank=True,null=True)
Copy the code

User interface serialization

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
class Meta:
    model = User
    fields = "__all__"
Copy the code

Login interface design

class UserLogin(APIView):
    def post(self,request):
        params = request.data
        userName = get_openid(params.get('code'))
        userInfo = params.get('userinfo')
        try:
            user = User.objects.get(username = userName)
        except Exception as e:
            user = None
        if user:
            # Update user information
            user = User.objects.get(username = userName)
        else:
            # Register a new user
            user = User.objects.create_user(username=userName,password=random_str(10))    
        # Manually generate JWT
        # Manually generate token validation
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        ret = {'code': '00000'.'msg': None.'data':{}}
        
        ret['msg'] = 'Authorization successful'
        ret['data'] = {
            'token': token,
            'user_id': user.id,
            'nickname': user.nickname
        }
        return JsonResponse(ret)
Copy the code

Parse the code to get the OpenID

class OpenidUtils(object):
    def __init__(self, jscode):
        self.url = "https://api.weixin.qq.com/sns/jscode2session"
        self.appid = APPID
        self.secret = SECRET
        self.jscode = jscode    # dynamic jscode returned from the front end

    def get_openid(self):
        url = self.url + "? appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"
        r = requests.get(url)
        openid = r.json()['openid']
        return openid
Copy the code

Small program login verification

For details about the login process, please refer to the official documents.

function getWXUserInfo() {
    const login = promisify(wx.login);
    const getUserInfo = promisify(wx.getUserInfo);

    return new Promise(function (resolve, reject) {
        _wxLogin();
        function _wxLogin() {
            login().then(function (res) {
                getUserInfo().then(function (r) {
                    let userInfo = r;
                    userInfo.code = res.code;
                    try {
                        wx.setStorageSync('userInfo', userInfo);
                    } catch (e) {
                        console.log(e)
                    }
                    if (userInfo && userInfo.code && userInfo.iv) {
                        resolve(userInfo);
                    }
                    else {
                        reject('wx login fail');
                    }
                }).catch(function (error) {
                    reject(error);
                });
            }).catch(function (error) { reject(error); }); }}); }// Login interface authentication
getWXUserInfo().then(function (data) {
    var result = {
        code: 0.data: {}};var params = {
        'code':data.code,
        'userinfo':data.userInfo
    }
    wx.request({
        url: '/api/login'.data: params,
        dataType: 'json'.method: 'POST'.success: function (response) {
            // Return success
            if (response.data && response.data.code == '00000') {
                try {
                    var resData = {
                        custNo: data.user_id,
                        nickname: data.nickname
                    };
                    result.code = 0;
                    result.data = resData;
                    resolve(result);
                }
                catch (e) {
                    console.warn(result)
                    // Login failed
                    result.code = 2; resolve(result); }}else {
                // Failed to get customNum
                console.warn(result)
                result.code = 1;
                result.data = 'get customNum fail'; resolve(result); }}})}Copy the code