I am getting an error like this in Twilio Voice Call:
Type of credential provided in access token does not match that of the registration. For example, you included the SID of an APS type
Credential in the access token for an Android application using GCM.
I already completed the setup for android, ios and node server side.
I have a question to resolve this issue.
Can I pass multiple VoiceGrant objects in AccessToken object like below at the server side:
const voiceGrant1 = new VoiceGrant({
outgoingApplicationSid: outgoingApplicationSid,
pushCredentialSid: pushCredSidObject['ios']['prod'] // iOS platform PUSH_CREDENTIAL_SID
});
const voiceGrant2 = new VoiceGrant({
outgoingApplicationSid: outgoingApplicationSid,
pushCredentialSid: pushCredSidObject['android']['prod'] // android platform PUSH_CREDENTIAL_SID
});
const token = new AccessToken(accountSid, apiKey, apiSecret);
token.addGrant(voiceGrant1);
token.addGrant(voiceGrant2);
Is it valid to add grant multiple times? If not, please provide me another solution.
I think possible solution could be when we request for token from application, we can pass extra params, so let's say for iOS you pass platform=iOS and for android you pass platform=android
Now when your node code get executed you can get those extra param by event.platform something like this just like you try to get identity and based on platform value you can add Grant as per needed.
Hope this helps :)
Related
I am implementing sign in with Apple. I can successfully see the Apple login page. I key in the correct credentials. It should be able to sign in/sign up to the firebase based on the returned value from Apple.
However I am getting this error Error: The supplied auth credential is malformed, has expired or is not currently supported. Something must be wrong at the firebase side? You may refer to the onPressAppleLogin function below on the logic. Many thanks!
What I have done:
In Firebase
Authentication with Sign-in provider Apple enabled
My service id is co.myexampleapp.signinwithapple
My authorization callback is https://my-example-app.firebaseapp.com/__/auth/handler
In developer.apple.com
I created a service id co.myexampleapp.signinwithapple with the service Sign In with Apple enabled
I added my-example-app.firebaseapp.com for the Domain and https://my-example-app.firebaseapp.com/__/auth/handler in the Return URLs
My React Native source code
import { appleAuthAndroid } from '#invertase/react-native-apple-authentication';
import firebase from 'react-native-firebase'
getRandomString = (length: any) => {
let randomChars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let result = ''
for (let i = 0; i < length; i++) {
result += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
}
return result
}
onPressAppleLogin = async () => {
const rawNonce = this.getRandomString(20);
const state = this.getRandomString(20)
appleAuthAndroid.configure({
clientId: 'co.myexampleapp.signinwithapple',
redirectUri: 'https://my-example-app.firebaseapp.com/__/auth/handler',
responseType: appleAuthAndroid.ResponseType.ALL,
scope: appleAuthAndroid.Scope.ALL,
nonce: rawNonce,
state,
});
const response = await appleAuthAndroid.signIn();
const appleCredential = await firebase.auth.AppleAuthProvider.credential(response.id_token, rawNonce)
const appleUserCredential = await firebase.auth().signInWithCredential(appleCredential) // error happens here!
}
This is 100% due to the wrong Services ID on the server or the client.
I was working on a project in which we have Django as the backend server the backend developer used a different Services ID on the server & I on the client-side used a different Services ID.
How we solved this issue.
Open the Firebase console in the general settings check the bundle ID of the ios app compare it with the bundle ID in your Xcode. Make sure the Services is ID is correct and you have the latest provisioning profile with the Services Id added inside it.
Read this article to understand how to create a service ID. https://firebase.google.com/docs/auth/android/apple?authuser=4
You need to add the same services ID that you created above in the firebase console where you enable apple auth service in the authentication section
In your case you need to add service id
co.myexampleapp.signinwithapple
in the input box that is shown in the screenshot.
There is some sort of error in initializing the credentials.
Three types of errors may occur:
In the response, the token may be get expired. In that time you can use refresh token function to get new token.
Have a look at the rules in the firebase, if you initialized your app in the locked mode read and write will be set to false. If it so, change it to true.
Check whether you have enabled Api keys.
Important Check whether you enabled the third party access for the Apple Id.
Since the problem is with token, I suggest you to check the following.
Make sure you provided your email in support email in firebase project settings.
Try logging out before performing signing in operation. Due to improper logout during development this may happen.
Make sure you always logout before signin. Helped me in some cases.
Device time - since the token generated will be based on timestamp.
I'm using sign_in_with_apple and I've got the signin working for ios but the android component is not working.
I've had a look through the docs and issues where this is asked but there are no clear answers. https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple
I'm stuck on the part of the docs for this plugin that say:
On the Sign in with Apple callback on your sever (specified in
WebAuthenticationOptions.redirectUri), redirect safely back to your
Android app using the following URL:
intent://callback?${PARAMETERS_FROM_CALLBACK_
BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
The PARAMETERS FROM CALLBACK BODY should be filled with the urlencoded
body you receive on the endpoint from Apple's server, and the package
parameter should be changed to match your app's package identifier (as
published on the Google Play Store). Leave the callback path and
signinwithapple scheme untouched.
Furthermore, when handling the incoming credentials on the client,
make sure to only overwrite the current (guest) session of the user
once your own server have validated the incoming code parameter, such
that your app is not susceptible to malicious incoming links (e.g.
logging out the current user).
The part that says: The PARAMETERS FROM CALLBACK BODY should be filled with the urlencoded body you receive on the endpoint from Apple's server. I'm unsure about how to get this and correctly format the PARAMATERS_FROM_CALLBACK_BODY part of the redirectURL to get this working for Android.
I was having exactly the same question and I actually opened up an issue on their repo yesterday.
I'm not sure if you are trying to set up your own backend server for callback or not, but to answer your question, the part you were having issue to understand is only apply for someone who need to implement their own API for call back.
I did get the Apple Sign In for Android to work(via web browser auth) with the following steps:
Note: Since you already got iOS part working, so I assume you got the basic configure taken care of already.
Set up the glitch.com service based off their document, this part is easy to follow.
And then you want to implement your signInWithApple call as the following reference Note: SERVER_AS_PER_THE_DOCS need update according to your glich service.
Future<FirebaseUser> signInWithApple() async {
var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple";
var clientID = "AS_PER_THE_DOCS";
final appleIdCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: clientID,
redirectUri: Uri.parse(
redirectURL)));
final oAuthProvider = OAuthProvider(providerId: 'apple.com');
final credential = oAuthProvider.getCredential(
idToken: appleIdCredential.identityToken,
accessToken: appleIdCredential.authorizationCode,
);
final authResult =
await SignInUtil.firebaseAuth.signInWithCredential(credential);
return authResult.user; }
I am developing a react-native application, in this application im trying to authenticating using oauth2. Now im trying to use a webview to retrieve my redirect_uri credentials, but im unsure how to retrieve it in react-native on a Android device.
I have found a example but it doessnt explain how to get the acces token in a variable, and I dont know how to implement this inside react-native.
for this purpose I am trying to use a implicit flow.
Grant Type: Implicit
The implicit grant type is used for mobile apps and web applications (i.e. applications that run in a web browser), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user's device. Also, this flow does not authenticate the identity of the application, and relies on the redirect URI (that was registered with the service) to serve this purpose.
The implicit grant type does not support refresh tokens.
The implicit grant flow basically works as follows: the user is asked to authorize the application, then the authorization server passes the access token back to the user-agent, which passes it to the application. If you are curious about the details, read on.
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
Integrate oauth2 with native (iOS/Android) mobile application
My question is what should my redirect_uri be?
How can I retrieve the variables on react-native Android?
Is 'implicit flow' the way to use on a mobile application?
First you start looking which oauth2 flowtype is the securest one for your application in question by looking what other recommend.
After that I looked at 'implicit versus password grant_type' and looked up the fields which are required:
https://www.rfc-editor.org/rfc/rfc6749
I made sure a authorized endpoint is active for testing (by making one active yourself with the correct grant_type) Next I wondered how to fill all the fields. By installing postman, i could analyze and make a POST call myself.
After that you look up your url which in my case was : localhost:8000/oauth/token
and post against it using postman.
I was stuck on the part that you can't use JSON on the request body, but instead the oauth request needed to be in 1 long parameter called 'body' as a string. This is the way a httprequest works.
//authorization grant type: Resource owner password-based.
const HOST_ADRESS = "192.168.104.137:8000"; //change with your own host
const client_id = "jpijpijpijpijipjipijipijipijipj";
fetch('http://'+HOST_ADRESS+"/oauth/token/", {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-cache'
},
body: "client_id=sfjwepifjpfweijgpeijSGIOEJOPGIWSJA35340537530708&grant_type=password&username="+username+"&password="+password
})
.then((response) => response.text())
.then((responseText) => {
console.log(responseText);
//redux succed do something.
//dispatch(actionsCreators.succesLogin(responseText));
})
.catch((error) => {
const data = {error: "A error happened"};
//redux error.
//dispatch(actionsCreators.errorLogin(data));
console.warn(error);
});
Hopefully someone else learns something coming across the steps I took.
Only need to save the token somewhere in a database to check (sql lite ) or realm.io (yay for next steps.)
First, you should choose the right grant type based on where you are trying to log in.
If the service is yours, you can go with grant type password.
If the service is third party, you can use implicit type. You provide redirect uri, which has to be registered with that particular service and which is used to redirect user after he is authentized.
Finally, there is a network API in React Native where you use fetch (see docs). As a second parameter to this function, you can provide additional informations and header. This is where you set all the required informations provided in the oAuth2 docs.
This is a very interesting example: https://github.com/bartonhammond/reactnative-oauth-hapi
I want to get the events list from a public Facebook page, and to do it I need an access token. This is not a problem when doing it server-side, because I can use both my secret and client app id in order to get an access token, but this is not possible on client-side (for example, on an iOS application), since it would make clear my app secret ID. What can I do? With the Facebook SDK for iOS, I think I can only get an access token making the user log-in, but, in my case, this is not necessary, since I only need to get a public list of events.
With PHP:
require '../facebook-php-sdk/facebook.php'; //MY FACEBOOK SDK
$facebook = new Facebook(array(
'appId' => '<#MYAPPID#>',
'secret' => '<#MYAPPSECRET#>', //<-- I CAN'T USE THIS ON CLIENT-SIDE!
));
Thanks
What I'm trying to do is to authenticate my Android app to the Google Cloud Endpoint.
Basically the endpoints should only allow my Android app to access the methods and nothing else.
I have done these things -
Create a client id using my SHA1 value in Eclipse in the Google Cloud Console.
Create a web client id in the Google Cloud Console for my endpoint project.
Add both these client id's in the "#Api" mentioned on each endpoint.
Add an extra "user" parameter in the endpoint methods.
Regenerate and deploy the backend to the cloud.
But when I'm running this the "user" is always coming as "null". I'm at my wits end trying to find a proper working method for doing all this.
I've searched many forums but no proper answers anywhere.
Here's another similar post Restrict access to google cloud endpoints to Android app
This is the reference I'm using -
https://developers.google.com/appengine/docs/java/endpoints/auth
Has anyone here done this before? My main goal is to not allow unauthenticated apps and outside world to access the endpoints, for obvious security reasons. I don't want to use end-user based authentication since I want to keep my app very simple.
It sounds like it's working as intended. You control which client apps can call your endpoint methods via the client IDs as you have already done. The User parameter is coming in as null precisely because you aren't doing end-user authentication. The User parameter represents an actual real user (Google Account). So if you don't need end-user authenticated methods, you can just simply not define the User parameter, or else ignore the null value. You said your problem is that the User parameter is set null. What are you expecting it to be in this scenario?
You need to call authenticate on the client, then possibly the library you're using will 'inject' the user information.
Here's what worked for me :
Let's say you have the keys below :
static final String WEB_CLIENT_ID = "somekeyfor webclientid.apps.googleusercontent.com";
static final String ANDROID_CLIENT_ID = "somekeyfor androidclientid.apps.googleusercontent.com";
static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;
Your Api anotation should look like this :
#Api(
name = "yourapiname",
clientIds = {CloudEndpoint.WEB_CLIENT_ID,CloudEndpoint.ANDROID_CLIENT_ID},
audiences = {CloudEndpoint.ANDROID_AUDIENCE},
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "myapp.app.com",
ownerName = "myapp.app.com",
packagePath = ""
)
)
In the annotation below, notice how your audience is the variable --> ANDROID_AUDIENCE which is equal to WEB_CLIENT_ID.
Now in your app side, when you create the googleAccountCredential object, you should pass in the Web Client Id like this :
mAccountCredentials = GoogleAccountCredential.usingAudience(getApplicationContext(),"server:client_id:" + "yourwebclientID");
Note that even if this is properly done, your user object in the endpoint might still coming out as Null if the account name you pass in mAccountCredentials.setSelectedAccountName("accontname") does not exist in the device. Therefore make sure the account name you pass does exist in the Android device by going to --> (Settings/Accounts)