第三方登录遇到的坑和注意事项 --- Google, Facebook
注: 目前 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'}); } });