Loading

Google Authentication的实现 - Odoo 安全登录

在前边的一篇文章中,我们提到了利用二次验证增强Odoo登录的可靠性:http://www.cnblogs.com/kfx2007/p/6023991.html

今天我们来具体实现这一步:

后端的实现

我们需要一个地方来存储二次验证的安全码,拓展用户字段:

class res_users(models.Model):
    _inherit='res.users'

    enable_google_auth = fields.Boolean(u'启用Google两步验证')

    otp_str = fields.Char('QR Codes')
    google_auth_img = fields.Binary('Google Authontication QR',compute="_get_qr_img")

安全码采用随机字符,并用二维码的方式呈现出来:

    @api.one 
    def btn_gen(self):
        base32 = pyotp.random_base32()
        self.otp_str = base32


    @api.one 
    def _get_qr_img(self):
        #check login 
        if '@' not in self.login:
            raise except_orm(_('Error!'),_('Invlid Login!'))
        totp = pyotp.TOTP(self.otp_str)
        qrcodes = totp.provisioning_uri(self.login)
        img = qrcode.make(qrcodes)
        buf = StringIO.StringIO()
        img.save(buf,'PNG')
        self.google_auth_img = buf.getvalue().encode('base64')

这里需要注意的是,web页面并不能直接将python的image展示出来,需要将其用base64 encode之后展示出来。

前端的实现

根据个人需求,前端的验证方式可以有多种,这里以密码+6位随机数字的方式为例:

class google(openerp.addons.web.controllers.main.Home):

    @http.route('/web/login',type='http',auth='public',website=True)
    def web_login(self,*args,**kargs):
        if request.httprequest.method=='POST' and not request.params.get('qsso'):
            #Check Google Authentication
            uids = request.registry.get('res.users').search(request.cr,openerp.SUPERUSER_ID,[('login','=',request.params['login'])])
            qcontext={}
            if not len(uids):
                qcontext['error'] =  _("User doesn't exist! Please contact system administrator!")
            user = request.registry.get('res.users').browse(request.cr,openerp.SUPERUSER_ID,uids)
            
            if user.enable_google_auth and user.otp_str:
                totp = pyotp.TOTP(user.otp_str)
                otpcode = totp.now()
                check_code = request.params['password'][-6:]
                check_passwd = request.params['password'][:-6]
                if request.params['password'][-6:] == otpcode:
                    request.params['password']=check_passwd
                    return super(google,self).web_login(*args,**kargs)
                else:
                    qcontext['error'] = 'Your Google Authentication Failed!'
                    return request.render('web.login', qcontext)
        return super(google,self).web_login(*args,**kargs)

主要的思路是当用户传过来的密码 截取后6位与生成的6位验证码进行验证,如果验证通过再去验证前几位的密码字符,否则直接不允许登录。

效果图如下:

登录界面失败以后的界面:

posted @ 2016-11-15 22:31  青岛欧姆网络科技  阅读(7008)  评论(0编辑  收藏  举报