django與小程序實現(xiàn)登錄驗證功能

之前用小程序做項目,因為后臺使用的java開發(fā),一切順利,但切換成django做RESTful API接口時,在登陸注冊時一直出現(xiàn)問題,網(wǎng)上搜索,借助一個網(wǎng)友的回答,找到了一種可行的解決方案,現(xiàn)記錄如下。

具體流程

  • 用戶點擊小程序頁面上的登錄授權認證
  • 通過微信自帶的認證獲取code
  • 調(diào)取登錄接口,將code傳入后臺
  • 后臺拿到code調(diào)用微信接口獲取openid等用戶信息
  • 后臺將openid作為用戶名,若存在則去校驗用戶信息,否則以此用戶名創(chuàng)建新用戶,密碼隨機生成
  • 將校驗結果或者創(chuàng)建信息返回給微信小程序端
  • 根據(jù)返回的信息完成用戶登錄校驗

django的用戶權限認證

django有一套自己的完善用戶模型,由于Django Auth自帶的User模型字段有限,我們需要對其進行拓展(直接使用也可以)

nickname = models.CharField(verbose_name=u'昵稱',max_length=50, blank=True)
user_avatar =  models.ImageField(verbose_name=u'用戶頭像', upload_to='image/%Y/%m/%d', default=u'image/default.png', max_length=500)
user_email = models.EmailField(verbose_name=u'用戶郵箱',max_length=254)
user_phone = models.BigIntegerField(verbose_name=u'手機號', null=True,blank=True)
user_birthday = models.DateField(verbose_name=u'出生日期', default = timezone.now)
user_sex = models.CharField(verbose_name=u'性別',max_length=6,choices=(('male','男'),('female','女')),default='male')
user_address = models.CharField(verbose_name=u'地址',max_length=550, blank=True,null=True)
signature = models.CharField(verbose_name=u'個性簽名',max_length=550, blank=True,null=True)

用戶接口序列化

from rest_framework import serializers

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

登陸接口設計

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:
            # 更新用戶信息
            user = User.objects.get(username = userName)
        else:
            #注冊新用戶
            user = User.objects.create_user(username=userName,password=random_str(10))    
        #手動生成JWT
        # 手動生成token驗證
        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'] = '授權成功'
        ret['data'] = {
            'token': token,
            'user_id': user.id,
            'nickname': user.nickname
        }
        return JsonResponse(ret)

解析code獲取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    # 前端傳回的動態(tài)jscode

    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

小程序的登陸驗證

具體登錄流程可以查閱官方文檔。

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);
            });
        }
    });
}

//登錄接口驗證
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) {
            // 返回成功
            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)
                    // 登錄失敗
                    result.code = 2;
                    resolve(result);
                }
            }
            else {
                // 獲取 customNum 失敗
                console.warn(result)
                result.code = 1;
                result.data = 'get customNum fail';
                resolve(result);
            }
        }
    })
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 小程序檔案館 - 登錄授權 智能小程序運行在百度 App 之類的宿主上時,相比普通的 H5 應用有一項很大的優(yōu) 勢...
    熊貓大俠請留步閱讀 1,298評論 1 0
  • 一、遇到授權 最近開發(fā)微信小程序,做登錄功能時遇到下圖。 看太懂,有幾處疑惑地方: 同事告訴我這是認證和授權,之前...
    dkvirus閱讀 15,065評論 3 21
  • 有個詞叫自作自受 懦弱無能、膽小如鼠、循規(guī)蹈矩,諸如此類性情的人,向來與自作自受都有著見不得人的關系。...
    靜下的繁星閱讀 611評論 4 3
  • 寒食時節(jié)曉雨殘,將雛挈婦上南山。 誰家墓冢青煙起,杜宇聲聲步更跚。 春日融融燕又來,踏青折柳放犁開。 鄰家稚子乘風...
    白云之外閱讀 427評論 3 7
  • 姓名:歐陽小紅 公司:上海日朗門窗有限公司 【日精進打卡第 63天】 【知~學習】 《六項精進》0遍共46遍 《大...
    平凡人生_d55b閱讀 243評論 0 0

友情鏈接更多精彩內(nèi)容