django와 애플릿이 로그인 검증 기능을 실현

11608 단어
이전에 작은 프로그램으로 프로젝트를 했는데 백엔드에서 사용하는 자바 개발로 모든 것이 순조롭게 진행되었지만 django로 전환하여 RESTful API 인터페이스를 만들 때 로그인 등록할 때 문제가 계속 발생했다. 인터넷 검색에서 한 네티즌의 대답을 빌려 실행 가능한 해결 방안을 찾았다. 현재 기록은 다음과 같다.
구체적 절차
  • 사용자가 애플릿 페이지의 로그인 인증 클릭
  • 위챗 자체 인증을 통해 코드 획득
  • 로그인 인터페이스를 가져와 코드가 백엔드로 전송
  • 백엔드에서 코드 호출 위챗 인터페이스로 Openid 등 사용자 정보 얻기
  • 백엔드에서 Openid를 사용자 이름으로 하고 존재하면 사용자 정보를 검사합니다. 그렇지 않으면 이 사용자 이름으로 새 사용자를 만들고 비밀번호는 무작위로 생성됩니다
  • 검사 결과나 생성 정보를 위챗 애플릿에 되돌려주기
  • 되돌아오는 정보에 따라 사용자 로그인 검사를 완료
  • 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)
    

    코드 해석 오픈 id 가져오기
    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    #        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);
                }
            }
        })
    }
    

    전재 대상:https://juejin.im/post/5c6b64bde51d457fa31e6a30

    좋은 웹페이지 즐겨찾기