【问题标题】:JJWT libary to generate token for authentication with Firebase on Android用于在 Android 上使用 Firebase 进行身份验证的 JWT 库生成令牌
【发布时间】:2017-06-04 15:36:51
【问题描述】:

我正在尝试实现 Linkedin 登录,然后使用 Firebase 进行身份验证。这样做的唯一方法是:

  1. 使用Linkedin登录,授予令牌here
  2. 获取 Linkedin 用户的 ID。
  3. 按照 Firebase 的指示制作令牌。
  4. 为了signInWithCustomToken就像它表示here一样,遵循here的过程:

    使用第三方 JWT 库创建自定义令牌

现在,我已经完成了所有这些。这是使用 JJWT 库生成令牌的代码:

long nowSeconds = System.currentTimeMillis()/1000;
        Date current_date = new Date(nowSeconds);
        KeyPair myKey = RsaProvider.generateKeyPair();
        long expMillis = nowSeconds + 3000;
        Date exp_time = new Date(expMillis);
        String compactJws = Jwts.builder()
                .setSubject(ACCOUNT_EMAIL)
                .setIssuer(ACCOUNT_EMAIL)
                .setAudience("https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit")
                .setIssuedAt(current_date)
                .setExpiration(exp_time)
                .setId(linkedinId)
                .signWith(SignatureAlgorithm.RS256, myKey.getPrivate())
                .compact();

但我的令牌格式不正确,因为:

iat 发布时间当前时间,自 UNIX 纪元以来的秒数

exp 过期时间 自 UNIX 纪元以来令牌过期的时间(以秒为单位)。最多可延迟 3600 秒 比iat。注意:这里只控制自定义token的时间 本身就过期了。但是,一旦您使用 signInWithCustomToken(),他们将保持登录到设备 直到他们的会话无效或用户退出。

因为 Firebase 需要秒数而不是日期。我不能在setIssuedAtsetExpiration 上传递一个长值,因为需要一个日期对象作为参数。

那么,我怎样才能把长值(秒)放在那里? 更新: 我找到了一种像这样传递时间戳的方法:

long nowSeconds = System.currentTimeMillis()/1000;
        Date current_date = new Date(nowSeconds);
        KeyPair myKey = RsaProvider.generateKeyPair();
        long expSeconds = nowSeconds + 3000;
        Date exp_time = new Date(expSeconds);
        String compactJws = Jwts.builder()
                .setSubject(ACCOUNT_EMAIL)
                .setIssuer(ACCOUNT_EMAIL)
                .setAudience("https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit")
                .claim("iat",current_date.getTime())
                .claim("exp",exp_time.getTime())
                .claim("uid",uid)
                .signWith(SignatureAlgorithm.RS256,myKey.getPrivate())
                .compact();

但我的 Token 格式还是不正确:

 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                          Process: com.example.qrcodereader, PID: 24239


com.google.android.gms.tasks.RuntimeExecutionException: com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The custom token format is incorrect. Please check the documentation.
                                                                          at com.google.android.gms.tasks.zzh.getResult(Unknown Source)
                                                                          at com.example.qrcodereader.LoginActivity$6.onComplete(LoginActivity.java:268)
                                                                          at com.google.android.gms.tasks.zzc$1.run(Unknown Source)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:148)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:7325)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                                                       Caused by: com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The custom token format is incorrect. Please check the documentation.
                                                                          at com.google.android.gms.internal.zzbix.zzcb(Unknown Source)
                                                                          at com.google.android.gms.internal.zzbiu$zzj.zza(Unknown Source)
                                                                          at com.google.android.gms.internal.zzbjf.zzcc(Unknown Source)
                                                                          at com.google.android.gms.internal.zzbjf$zza.onFailure(Unknown Source)
                                                                          at com.google.android.gms.internal.zzbja$zza.onTransact(Unknown Source)
                                                                          at android.os.Binder.execTransact(Binder.java:453)

有谁知道这里的错误是什么?实在想不通。

【问题讨论】:

    标签: android firebase token firebase-authentication jjwt


    【解决方案1】:

    Date con 不是用秒来构建的。它需要一个毫秒值。此代码不正确。

    Date current_date = new Date(nowSeconds);
    

    使用以下代码

    KeyPair myKey = RsaProvider.generateKeyPair();
    Date current_date = new Date();
    Calendar calendar = Calendar.getInstance(); 
    calendar.add(Calendar.SECOND, 3000);
    Date exp_time = calendar.getTime();
    String compactJws = Jwts.builder()
            .setSubject(ACCOUNT_EMAIL)
            .setIssuer(ACCOUNT_EMAIL)
            .setAudience("https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit")
            .setIssuedAt(current_date)
            .setExpiration(exp_time)
            .setId(linkedinId)
            .signWith(SignatureAlgorithm.RS256, myKey.getPrivate())
            .compact();
    

    如果您想使用第二种方式.claim() 将值除以 1000 得到秒数

    .claim("exp",exp_time.getTime()/1000)
    

    【讨论】:

    • 嗨@pedrofb,谢谢你的帮助,我可以在那里看到我的错误。但这里的主要问题是我生成了自己的私钥,而我需要使用 Firebase 给我的特定私钥。
    • 根据firebase.google.com/docs/auth/admin/create-custom-tokens,如果您创建自定义 JWT 令牌,您必须使用自己的私钥对其进行签名。 Firebase 不会为您提供 RSA 密钥。因此,您必须生成和存储密钥对并使用它来签名和验证。可能是firebase SDK也做这个功能
    • 基本上,Firebase 为我提供了一个项目的服务帐户私钥,它是字符串格式的,我将其转换为我必须在 signWith 方法中使用的我的 RSA 私钥。
    • 好吧,我不知道。那么您的问题是如何从您的字符串构建 RSA PrivateKey?您能否在问题中发布第一个字符或查看格式的关键?可能它是 PEM 编码的。可能它有标题-----BEGIN PRIVATE KEY-----,内容是用base64编码的
    • 嘿,不,没关系,我昨天已经解决了我的问题:D
    猜你喜欢
    • 2018-03-05
    • 2020-04-13
    • 2018-08-29
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 2021-11-02
    相关资源
    最近更新 更多