关于javascript:从现有的id_token获取Auth0 access_token

Get Auth0 access_token from existing id_token

我正在使用auth0对我的单页应用程序(基于React)构建的登录进行身份验证。我主要使用基本API调用(在此处列出)。

我正在使用的过程是:

当用户在我的应用的登录页面上输入用户名/电子邮件和密码时,
使用这些值向/oauth/ro发送POST请求-这是该代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
export const login = (params, err) => {
  if (err) return err
  const {email, password} = params
  const {AUTH0_CLIENT_ID, AUTH0_DOMAIN} = process.env
  return fetch(`${AUTH0_DOMAIN}/oauth/ro`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      'client_id': AUTH0_CLIENT_ID,
      'username': email,
      'password': password,
      'connection': 'Username-Password-Authentication',
      'grant_type': 'password',
      'scope': 'openid',
      'device': '',
      'id_token': ''
    })
  })
  .then(response => response.json())
  .then(json => {
    const {id_token, access_token} = json
    setCookieValue('id_token', id_token) // utility function I wrote
    return getProfile(access_token)
      .then(data => {
        const {user_id, email: emailAddress, picture, name} = data
        return {id_token, user_id, emailAddress, picture, name}
      })
  })
  .catch(error => console.log(`ERROR: ${error}`))
}

这都是通过Redux发送的,并且用户已登录(假设用户名/密码正确)。

但是,我正在尝试弄清在刷新页面/返回到应用程序时如何保留登录名。我将id_token(这是一个JWT)保存在浏览器的Cookie中,可以在应用程序呈现服务器端时获取。我可以解码JWT并获取有效负载(sub是auth0中的用户ID)。但是,要获取配置文件数据,我需要使用/oauth/ro POST请求时Auth0提供的access_token。显然,如果JWT令牌已过期,它将拒绝它并保持用户注销。

这是我的代码,用于解码JWT(在应用渲染时发生):

1
2
3
4
5
6
7
8
9
10
const ID_TOKEN = req.cookies.id_token || false
if (ID_TOKEN) {
  verifyJwt(ID_TOKEN, (err, decoded) => {
    if (err) { console.log(`JWT Verification error: ${err}`) }
    else {
      const {sub} = decoded
      getProfile(sub).then(data => store.dispatch(fetchUserDetails(data))) // fails as `sub` (the user id) is not the `access_token` which it requires
    }
  })
}

我再次尝试使用/oauth/ro调用,但是这次指定了"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer"并使用了从cookie中检索到的id_token并指定了device。但是,当我执行此调用时,我从Auth0获得此错误:

1
2
3
4
{
 "error":"invalid_request",
 "error_description":"there is not an associated public key for specified client_id/user_id/device"
}

所以我的问题是,要从id_token JWT中获取access_token,我需要进行什么API调用?

此外,作为奖励-当我执行POST请求登录时,password正在通过纯文本传输。发送到auth0时如何加密,以便他们可以解密回来?我假设它涉及使用auth0提供的client_secret,但是我不确定如何去做。


无需任何类型的用户交互即可以编程方式刷新令牌的能力是通过使用刷新令牌来实现的。但是,这不适用于基于浏览器的应用程序,因为刷新令牌是长期存在的凭证,并且浏览器的存储特征会使它们有太大的泄漏风险。

如果要继续使用资源所有者密码凭据授予,则可以选择让用户在令牌过期时再次输入凭据。或者,通过身份验证,您可以获得所需的用户信息并启动特定于应用程序的会话。这可以通过让服务器端逻辑创建应用程序特定的会话标识符或JWT来实现。

您还可以停止使用资源所有者密码凭据授予,并将用户重定向到Auth0身份验证页面,该页面除了将令牌返回到您的应用程序之外还将为用户维护经过身份验证的会话,这意味着当令牌和应用程序过期时再次重定向到Auth0,用户可能不需要手动重新输入凭据,因为Auth0会话仍然有效。

关于以明文形式发送的密码;资源所有者端点依赖于HTTPS,因此数据在协议级别进行了加密。您还必须在自己的应用程序中使用HTTPS进行任何通信,包括任何类型的用户凭据。

还请注意,您可以通过使用范围来控制ID令牌中返回的内容,具体取决于所涉及的信息量,如果您发信号表示您希望这样做,甚至可能不需要进行额外的调用来获取用户个人资料要包含在ID令牌本身中的信息。