首页 > 解决方案 > 如何使用谷歌身份从多个设备登录?

问题描述

如何使用 Google 身份平台作为我自己的服务的登录/注册系统?具体来说 - 我怎样才能做到这一点并支持来自不同设备的同一用户登录?

用于 web 服务,没有 npm 模块的 nodejs:passportjs / googleapis / google-auth-library。

我的想法:用户打开 myClientApp/login 页面并单击 GoogleLogIn 按钮,该按钮将要求他授权我的服务用于他的 Google 帐户的特定范围。然后我获取刷新令牌和访问令牌并将其保存在数据库中,然后使用 cookie 将刷新令牌发送到客户端。每当我调用自己的服务 API 时,我都会从 cookie 发送刷新令牌。只要我的数据库中保存了有效的访问令牌或刷新令牌未过期 - 我将匹配该刷新令牌的用户视为我的服务的活动会话。

安全问题:cookies攻击,刷新令牌很容易从浏览器访问。可以使用 https / 加密和更多方法来保护 cookie 及其价值。仍然 - 有人可以将 cookie 从一台计算机复制到另一台计算机!

多次登录问题:如果用户在不同的设备上登录,将创建一个新的刷新令牌。用户登录的前一个设备现在将在 cookie 中保存错误的刷新令牌...

OpenID 能解决这个问题吗?我需要使用 JWT 吗?在我自己的服务中使用 Google 身份登录同时支持同一用户的多个设备登录的最安全方法是什么?

标签: google-oauthgoogle-identity

解决方案


First, make sure that you really understand the security implications for what you want to do.

For example, NEVER send the Refresh Token to a client.

If you want to use the same tokens for the same client on multiple devices, you have a chicken and egg situation. How do you "authenticate" the user at each device. How do you know that user "John" is actually user "John" but on a different device the first time?

Your goal is not to trade convenience for less security. Your goal should always be security first, no matter the inconvenience.

A better approach is to let Google authenticate and authorize a user on each device. They only have to do this once per device. Your backend systems keep track of the Refresh Token issued for each device. You can then generate the Access Tokens and Identity Tokens when needed - they expire after one hour anyways. Store a cookie on the user's device that identifies them to your system so that you can look up who they are, get the Refresh Token, create new Access Tokens, etc.

There is a limit to the number of Refresh Tokens that can be issued before the oldest ones are voided. I think the number is 50. This is usually not a problem. If a Refresh Token is invalid, just put the user back thru the authenticate process and store the new token.

Also provide the user with a sign-out method that removes all stored tokens in your system.

The cookie that you store on the client's devices should be opaque meaning that there is no stored information in the cookie and the cookie is only valid for that device and no other devices. This solves the stolen cookie moved to another device problem.

I will now touch on some of your questions:

My idea: User opens myClientApp/login page and clicks on GoogleLogIn button which will ask him to authorize my service for specific scopes of his Google account.

Google OAuth does not work that way. You send the user to a URL, Google manages all display and input with the end user. Once everything is complete a callback URL on your server is called and you are passed a code. The exact details depend on the type of OAuth Flow that you are using.

I then get the refresh token & access token and save it in DB, then send the refresh token to the client with cookie.

During the OAuth Flow you will request the Access Token, Refresh Token and Identity Token. The Refresh Token is saved in the database. Never send this token to the client. Read my suggestion above about creating an opaque cookie that you send to the client.

Security problems: cookies attacks, and the refresh token is easily accessed from the browser. Could use https / encryption and more methods to secure the cookie and it's value. Still- someone could copy the cookie from one computer to another!

Create an opaque cookie that is only valid for that device and no other devices. If a client sends you a cookie intended for a different device, consider this a problem and invalidate all cookies, tokens, etc for this user on all devices.

Multiple login problems: If the user login on different device, a new refresh token will be created. The previous device the user logged in to will now hold a wrong refresh token in the cookie...

I covered this issue above. Store the Refresh Token generated for each device in your DB. Consider each device / Refresh Token / cookie as a set.

Could the OpenID solve this? Do I need to use JWT? What is the most secure way to use Google Identity login in my own service while supporting multiple devices login for the same user?

By Open ID I think you mean Open ID Connect (OIDC). This is already integrated into Google OAuth and this is the part that generates the Identity Token.

Do I need to use JWT?

Google OAuth Tokens are generated from Signed JWTs. However for the most part you do not need to worry about the format of tokens. Google provides endpoints that validate and decode Google OAuth tokens.

What is the most secure way to use Google Identity login in my own service while supporting multiple devices login for the same user?

I covered this question in the first part of my answer above.


推荐阅读