第三方登录遇到的坑和注意事项 --- Google, Facebook

时间:2024-03-12 19:53:32

: 目前 Google, Facebook 出于安全原因, 不支持在嵌入式浏览器(webview)中进行登录. 

 

一. Google 登录

  1. 注册 Goolge 开发者账号

  网址: https://console.developers.google.com/apis/credentials

 

  2. 在控制面板中获取凭据(Credentials)并新建一个项目

 

  凭据生成时, 需要设置 名称 / 验证Javascript脚本来源的域名 / 验证后生定向的路径. 

  还会自动生成: ClientID, Client secret, Creation date

  : 如果处在开发阶段, 虽然可以在验证来源的域名中加入  http://localhost:8080 , 但开发时会感觉很不方便. 因为现在后台服务基本都是https的. 不能交互, 我知道2种解决办法

  a. 为本地机配置 https 证书. 

  可参考: https://juejin.cn/post/6844903863137337357

  b. 下载并安装 ngrok, 然后注册账号, 并根据 token 启动 ngrok 服务, 使公网可以直接访问 localhost 服务. 

  网址: dashboard.ngrok.com

  文档: http://ngrok.cn/docs.html

  启动: #ngrok authtoken 授权码

      #/Applications/ngrok http 8080

  启动后就可以将分配到的域名配置到 Google 凭据的设置中. 

 

  3. OAuth 同意屏幕(consent screen): 可以在这里设置测试用户等

 

  4. 域名验证(Domain verification) : 在后台服务器上进行验证, 验证域名拥有者

 

  5. 在 Library 中添加需要的服务, 如果没在首页中看到需要服务, 可以使用搜索进行查找. 

这里我们只需要查看用户的基本信息, 因此只需要 Google.People.API 这个服务. 把这个服务设置为 Enabled

  到此, 在 Google 开发者账号中设置基本完成. 

 

  6. 在页面中嵌入 HTML 和 Javascript

  文档: https://developers.google.com/identity/gsi/web/guides/automatic-sign-in-sign-out

<div id="g_id_onload"
                    data-client_id="CLIENT-ID"
                    data-context="signin"
                    data-ux_mode="popup"
                    data-callback="aaa"
                    data-auto_select="false">
                </div>

                <div id="g_id_signin" class="g_id_signin"
                    data-type="standard"
                    data-shape="rectangular"
                    data-theme="outline"
                    data-text="signin_with"
                    data-size="large"
                    data-logo_alignment="left"
                    data-width="280"
                >
                </div>

  注: data-auto_select="true", 开启自动登录

var apiUrl = \'https://accounts.google.com/gsi/client?onload=init\'
            var script = null
            var el = document.getElementById(\'gl_btn\')
            var btnContainer = document.querySelector(\'#g_id_signin\')

            if(el){
                try {
                    console.log(\'gl removed\', google)
                    console.log(\'create google login button\')
                    google.accounts.id.initialize({
                        client_id: \'1049348858791-omlrdpcrm5rtneqm1nrp8c9eviu9gl7o.apps.googleusercontent.com\',
                        callback: aaa,
                    });
                    google.accounts.id.prompt((notification) => {
                        if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
                            console.log(\'continue with another identity provider.\')
                        }
                    });
                    google.accounts.id.renderButton(
                        btnContainer,
                        {
                            icon: \'standard\',
                            size: \'large\',
                            shape: \'rectangular\',
                            theme: \'outline\',
                            text: \'signin_with\',
                            width: \'280\',
                        }
                    )

                    return
                }catch(e) {
                    console.log(\'没有 google 对象\')
                }
            }
            script = document.createElement(\'script\')
            script.src = apiUrl
            script.id = \'gl_btn\'
            script.setAttribute(\'async\', true)
            script.setAttribute(\'defer\', true)
            script.onreadystatechange = script.onload = function () {
                if (!script.readyState || /loaded|complete/.test(script.readyState)) {
                    setTimeout(function () {
                        console.log(\'google 脚本加载完成\')
                    }, 500)
                }
            }
            document.getElementsByTagName(\'head\')[0].appendChild(script)

 

 

二. Facebook 登录

  1. 注册 Facebook 开发者账号

  网址: https://developers.facebook.com/, 点击 "登录", 并注册登录

 

  2. 登录 Facebook 开发者账号, 点击 "我的应用(My App)"

 

  3. 创建应用

 

  4. 添加商品, 需要用到的 Facebook 服务, 这里我添加了"Facebook登录", 在这里添加 Javascript来源域名和跳转地址

  注: 这个商品不需要"验证" , 可直接授权

 

  5. 在应用审核中申请权限和功能, 如: public_profile, email, 这些权限, 大部分需要验证和购买才能使用.

 

  6. 设置 Facebook 登录: 设置网址, 生成代码等

  7. 代码: 因为使用Facebook生成的按钮登录失败, 所以只好自写按钮, 再调用 FB 对象来进行登录了. 

HTML

<div @click="fbLogin" class="button_green_big fb-btn">
                    <img :src="fbLogo" alt="" srcset="">
                    <span>Facebook Login</span>
                </div>

 

Javascript

var self = this
            var apiUrl = \'https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v12.0&appId=\' + config.appIdGL + \'&autoLogAppEvents=1\'
            var script = null
            var el = document.getElementById(\'fb_btn\')

            if(el){
                try {
                    console.log(\'fb removed\', FB)
                    FB.init({
                        appId            : config.appIdGL,
                        autoLogAppEvents : true,
                        xfbml            : true,
                        version          : \'v12.0\'
                    });
                    return
                }catch(e) {
                    console.log(\'没有 FB 对象\')
                }
            }
            script = document.createElement(\'script\')
            script.src = apiUrl
            script.id = \'fb_btn\'
            script.setAttribute(\'async\', true)
            script.setAttribute(\'defer\', true)
            script.setAttribute("nonce", "6Jv8HtT6")
            script.setAttribute("crossorigin", "anonymous")
            script.onreadystatechange = script.onload = function () {
                if (!script.readyState || /loaded|complete/.test(script.readyState)) {
                    setTimeout(function () {
                        console.log(\'facebook 脚本加载完成\', FB)

                        FB.getLoginStatus(function(response) {
                            if (response.status === \'connected\') {
                                console.log(\'FB login accessToken:\', response)
                                self.sendFBToken(response.authResponse.accessToken)
                            }else{
                                console.log(\'FB login status: \', response)
                            }
                        });
                        
                    }, 500)
                }
            }
            document.getElementsByTagName(\'body\')[0].appendChild(script)

  

  : 在调用 FB.login() 方法时, 需要设置需要的权限 {scope: \'public_profile,email\'}

FB.getLoginStatus(function(response) {
                if (response.status === \'connected\') {
                    console.log(\'FB login accessToken:\', response);
                    self.sendFBToken(response.authResponse.accessToken)
                    self.getProfile()
                }else{
                    console.log(\'FB login status: \', response)
                    FB.login(function(response){
                        console.log(\'FB login response: \', response)
                        if (response.status === \'connected\') {
                            self.sendFBToken(response.authResponse.accessToken)
                            self.getProfile()
                        }else {
                            // user FB取消授權
                            console.log("Facebook帳號無法登入");
                        }
                    }, {scope: \'public_profile,email\'});
                }
            });