首页 > 代码库 > Google Authentication的实现 - Odoo 安全登录

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位验证码进行验证,如果验证通过再去验证前几位的密码字符,否则直接不允许登录。

效果图如下:

技术分享

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

技术分享

Google Authentication的实现 - Odoo 安全登录