You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ember.js中实现谷歌登录认证(无需Torii)

无需Torii的Ember.js谷歌登录认证实现方案

核心思路

直接基于谷歌官方的Google Identity Services(原Google Sign-In JavaScript API),结合Ember.js的组件化特性或初始化器实现登录逻辑,无需依赖停更的Torii;若需要会话管理,可搭配最新版的ember-simple-auth(完全适配当前Ember版本)。


完整实现步骤

1. 修正index.html配置

你现有配置已包含Client ID和谷歌脚本,仅需调整注释位置避免HTML解析问题:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Signin</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Google OAuth2 Client ID -->
    <meta name="google-signin-client_id" content="93818-913ria6b3vcjh2.apps.googleusercontent.com">
    {{content-for "head"}}

    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/signin.css">

    {{content-for "head-footer"}}
  </head>
  <body>
    {{content-for "body"}}
    <!-- Google Identity Service 加载脚本 -->
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <script src="{{rootURL}}assets/vendor.js"></script>
    <script src="{{rootURL}}assets/signin.js"></script>

    {{content-for "body-footer"}}
  </body>
</html>

2. 组件化登录按钮(推荐方案)

将登录逻辑封装为Ember组件,避免全局函数污染,同时方便复用:

组件逻辑文件 app/components/google-login-button.js

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';

export default class GoogleLoginButtonComponent extends Component {
  @service session; // 若使用ember-simple-auth,注入会话服务

  constructor() {
    super(...arguments);
    // 初始化谷歌认证实例
    window.gapi.load('auth2', () => {
      window.gapi.auth2.init({
        client_id: '93818-913ria6b3vcjh2.apps.googleusercontent.com'
      });
    });
  }

  @action
  async handleSignIn(googleUser) {
    // 获取用户核心信息
    const profile = googleUser.getBasicProfile();
    console.log('用户ID:', profile.getId());
    console.log('邮箱:', profile.getEmail());
    console.log('用户名:', profile.getName());
    console.log('头像地址:', profile.getImageUrl());

    // 获取ID Token(用于后端验证身份)
    const idToken = googleUser.getAuthResponse().id_token;

    // 可选:用ember-simple-auth保存会话
    await this.session.authenticate('authenticator:google', idToken);
  }

  @action
  handleSignOut() {
    const auth2 = window.gapi.auth2.getAuthInstance();
    auth2.signOut().then(() => {
      // 可选:销毁ember-simple-auth会话
      this.session.invalidate();
    });
  }
}

组件模板文件 app/templates/components/google-login-button.hbs

<h2><center>使用谷歌账号登录</center></h2>
<div class="g-signin2" data-onsuccess={{this.handleSignIn}}></div>
{{#if this.session.isAuthenticated}}
  <button {{on "click" this.handleSignOut}}>退出登录</button>
{{/if}}

在页面中使用组件

在需要登录功能的模板中引入组件:

<GoogleLoginButton />

3. 自定义ember-simple-auth认证器(可选)

若需要会话持久化和权限管理,创建谷歌专属认证器:
app/authenticators/google.js

import BaseAuthenticator from 'ember-simple-auth/authenticators/base';

export default class GoogleAuthenticator extends BaseAuthenticator {
  async authenticate(idToken) {
    // 调用后端API验证ID Token合法性,返回用户会话数据
    const response = await fetch('/api/auth/google', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ id_token: idToken })
    });
    const data = await response.json();

    // 返回会话数据,ember-simple-auth会自动存储到本地
    return { token: data.token, user: data.user };
  }

  async restore(data) {
    // 页面刷新后验证会话有效性
    if (data.token) return data;
    throw new Error('会话已失效');
  }

  async invalidate() {
    // 可选:调用后端接口销毁服务器端会话
    await fetch('/api/auth/logout', { method: 'POST' });
  }
}

4. 简化版:全局函数获取用户信息

若不想封装组件,可通过Ember初始化器定义全局登录回调:
app/initializers/google-auth.js

import { registerDestructor } from '@ember/destroyable';

export function initialize(application) {
  // 定义谷歌登录成功回调
  window.onSignIn = function(googleUser) {
    const profile = googleUser.getBasicProfile();
    // 直接获取并处理用户信息
    console.log('用户邮箱:', profile.getEmail());
    console.log('用户名:', profile.getName());
    const idToken = googleUser.getAuthResponse().id_token;
    // 此处可添加登录逻辑(如调用后端、存储到本地)
  };

  // 应用销毁时清理全局函数
  registerDestructor(application, () => {
    delete window.onSignIn;
  });
}

export default { initialize };

关键注意事项

  • 确保谷歌开发者控制台已配置正确的JavaScript授权来源(如http://localhost:4200)
  • ID Token必须通过后端验证,禁止仅依赖前端数据信任用户身份
  • 若使用ember-simple-auth,需确保安装的是最新稳定版(适配Ember 3.x及以上版本)

内容的提问来源于stack exchange,提问作者hariharan baskaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:09:24