Error: Firebase ID token has no "kid" claim - firebase

Firebase documentation states that custom claims can be accessed like so:
admin
.auth()
.verifyIdToken(idToken)
.then((claims) => {
if (claims.admin === true) {
// Allow access to requested admin resource.
}
});
I have implemented Firebase auth following this sample project and tutorial. Specifically, the token is being decoded inside Next.JS' getServerSideProps here.
It's also worth mentioning that I'm running this project in development mode with Firebase Emulators.
So, on calling:
verifyIdToken(token)
I get this error message:
Error: Firebase ID token has no "kid" claim. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
Any idea where I'm failing?
---------- UPDATE ----------
The decoded token has this info:
{
"header":{
"alg":"none",
"typ":"JWT"
},
"payload":{
"email":"user#test.test",
"email_verified":false,
"auth_time":1626004181,
"user_id":"MY_USER_ID",
"firebase":{
"identities":{
"email":[
"user#test.test"
]
},
"sign_in_provider":"password"
},
"iat":1626004181,
"exp":1626007781,
"aud":"MY_FIREBASE_PROJECT_ID",
"iss":"https://securetoken.google.com/MY_FIREBASE_PROJECT_ID",
"sub":"SOME_KEY"
}
}

Related

How to get Google refresh token with knpuniversity/oauth2-client-bundle?

I use knpuniversity/oauth2-client-bundle and league/oauth2-google to connect users in my Symfony 4 web app using a "Sign in with Google" feature. I followed this tuto. I registered my app in Google.
I set access_type: offline in the knpu.oauth2.client.google configuration (config/packages/knpu_oauth2_client.yaml file)
I try to get the user refresh token in my GoogleAuthenticator::getUser(League\OAuth2\Client\Token\AccessToken $credentials) method (which extends KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator).
Unfortunately, $credentials->getRefreshToken() always returns null.
Why don't I get the user refresh token ?
As per documentation, "Refresh tokens are only provided to applications which request offline access". So, when instantiating the provider you need to set the accessType.
use League\OAuth2\Client\Provider\Google;
$provider = new Google([
'clientId' => '{google-client-id}',
'clientSecret' => '{google-client-secret}',
'redirectUri' => 'https://example.com/callback-url',
'accessType' => 'offline',
]);
In knpu_oauth2_client configuration, you can do:
google:
type: google
client_id: '%env(OAUTH_GOOGLE_CLIENT_ID)%'
client_secret: '%env(OAUTH_GOOGLE_CLIENT_SECRET)%'
redirect_params: {}
access_type: offline

How to properly configure Amplify Analytics?

I need some help understanding how to configure AWS Pinpoint analytics in Amplify. I'm currently using Amplify for Auth and have it configured like this in my index.js file:
export const configureAmplify = () => {
window.LOG_LEVEL="DEBUG"
Hub.listen('auth', data => handleAmplifyHubEvent(data))
Hub.listen('analytics', data => handleAmplifyHubEvent(data))
Amplify.configure({
Auth: {
identityPoolId: "redacted",
region: "us-west-2",
userPoolId: "redacted",
userPoolWebClientId: "redacted",
mandatorySignIn: false,
cookieStorage: {
domain: process.env.NODE_ENV === 'development' ? "localhost" : "redacted",
path: '/',
expires: 1,
secure: false
}
}
})
}
To add Analytics, I started by adding this to my configureAmplify() function:
Analytics: {
disabled: false,
autoSessionRecord: true,
AWSPinpoint: {
appId: 'redacted',
region: 'us-east-1',
endpointId: `wgc-default`,
bufferSize: 1000,
flushInterval: 5000, // 5s
flushSize: 100,
resendLimit: 5
}
}
Upon user sign-in or refresh from cookie storage I called
Analytics.updateEndpoint({
address: user.attributes.email, // The unique identifier for the recipient. For example, an address could be a device token, email address, or mobile phone number.
attributes: {
},
channelType: 'EMAIL', // The channel type. Valid values: APNS, GCM
optOut: 'ALL',
userId: user.attributes.sub,
userAttributes: {
}
})
After doing this, it seems to me that the data in the Pinpoint console is not accurate. For example, there are currently 44 sessions displayed when no endpoint filter is applied. If I add an endpoint filter by userAttributes: userId then no matter which ID I select, it shows all 44 sessions associated with that user. I suspect that is because the EndpointID is established at startup, and is not changed by the updateEndpoint call.
I have also tried omitting the Analytics key when I initially configure Amplify, and then calling Analytics.configure() after the user is signed in. With this approach, I can construct a user-specific endpointId. However, I think that doing it this way will mean that I don't capture any of the Authentication events (sign-in, sign-up, auth failure), because Analytics is not configured until after they occur.
So my question is what is the proper timing for configuring Amplify Analytics? How can I accurately capture session, auth and custom events, AND uniquely identify them by user id?
It's not necessary to assign a custom endpoint id, amplify will handle it automatically and all events will be tracked per device. Instead, if you really need it, update the endpoint with the userId after sign-in.
The advantage of adding the userId is that all the endpointIds of a user are automatically associated to that userId, thus when you update a user's attribute, it will be synchronized across the endpoints.
As you are using Cognito, Amazon Cognito can add user IDs and attributes to your endpoints automatically. For the endpoint user ID value, Amazon Cognito assigns the sub value that's assigned to the user in the user pool. To learn about adding users with Amazon Cognito, see Using Amazon Pinpoint Analytics with Amazon Cognito User Pools in the Amazon Cognito Developer Guide.

Firebase Admin SDK : Verifying ID tokens from the REST API

I'm trying to verify Id tokens received by signing in with the REST API for authentication by using the verifyIdToken(idToken) method in the Admin SDK but instead of getting the decoded token I get the error:
Firebase ID token has incorrect "iss" (issuer) claim. Expected "https://securetoken.google.com/"" but got "https://identitytoolkit.google.com/". Make sure the ID token comes from the same Firebase project as the service account used to authenticate this SDK. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
As I said above I'm getting my token from the REST API, so I was expecting this to work.
The response I get from the API is this:
{
"kind": "identitytoolkit#VerifyPasswordResponse",
"localId": "pu0yjIc8tnR85X2gERdtLx684DK2",
"email": "test#test.com",
"displayName": "",
"idToken": "<token-id>",
"registered": true
}
Is this considered a custom token? if so, how can I verify it?
As of Sep 2018, the issuer of the ID Token returned by REST API seems to be changed from https://identitytoolkit.google.com/ to https://securetoken.google.com/. And I can successfully verify this id token in firebase admin SDK.
[Edit]: The firebase admin SDK still fails to verify the Facebook ID Token returned by identitytoolkit's verifyAssertion REST API.
According to Google Developer
Calling the tokeninfo endpoint
An easy way to validate an ID token for debugging and low-volume use
is to use the tokeninfo endpoint. Calling this endpoint involves an
additional network request that does most of the validation for you,
but introduces some latency and the potential for network errors.
To validate an ID token using the tokeninfo endpoint, make an HTTPS
POST or GET request to the endpoint, and pass your ID token in the
id_token parameter. For example, to validate the token "XYZ123", make
the following GET request:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
{
// These six fields are included in all Google ID Tokens.
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"iat": "1433978353",
"exp": "1433981953",
// These seven fields are only included when the user has granted the "profile" and
// "email" OAuth scopes to the application.
"email": "testuser#gmail.com",
"email_verified": "true",
"name" : "Test User",
"picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
"given_name": "Test",
"family_name": "User",
"locale": "en"
}

How to check Item exists in Firebase Database? - react-native-firebase

Currently, I am using https://github.com/invertase/react-native-firebase for my project. I have a custom database for users and I want to check if the user exists or not by email.
Here is a screenshot of the database:
Here's a generic firebase method but you may need to reconfigure the method to suit your data structure. Please refer to the official docs if you wish to know more.
firebase.database()
.ref(`/users`)
.orderByChild("email")
.equalTo(email)
.once("value")
.then(snapshot => {
if (snapshot.val()) {
// data exist, do something else
}
})
You can also query the registration status with hasChild method. Refer to your root path and query with .once and check the result returned.
export function checkUserExist(email) {
return(dispatch) => {
firebase.database().ref(`/ExistingUser/`)
.once('value', snapshot => {
if(snapshot.hasChild(email)) {
dispatch({
type: FIREBASE_USER_EXISTED
});
} else {
dispatch({
type: FIREBASE_USER_NOT_EXISTED,
});
}
});
}
}
Another preferred method would be using the fetchProvidersForEmail method provided by Firebase. It takes an email and returns a promise that resolves with the list of providers linked to that email if it is already registered, refer here.
Is there a good reason to store users credential in your database? In my daily practice, I would use the createUserWithEmailAndPassword provided by Firebase for security purposes, refer here. Just make sure rules are defined properly to prevent unauthorized access.

how to use Meetup API with meteor

I'm trying to query the Meetup API using meteor,i tried a Meteor package.
when i call the function below i get this error.
API requests must be key-signed,oauth-signed, or accompanied by a key:
Meteor.methods({
getGroups:function(){
Meetup.get('2/events', {
member_id: 'self',
status: 'upcoming',
rsvp: 'yes'
}, {user: this.userId});
}
})
I used the accounts-meetup package ,and i auth successfuly.
You need to provide in your request an access key https://secure.meetup.com/meetup_api/key/ . Also look here Modifying user.profile using Accounts.onCreateUser for loginWithMeetup

Resources