I've got "authorize" to work against the Coinbase API. It authorizes and I get an email from then to say my app has been associated with my account. I also get redirected back to my app using Deep Linking.
The problem is "authorize" doesn't return anything. I would have expected to receive something?
import { authorize } from 'react-native-app-auth';
authorize() {
authorize(config)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
I have also tried this but it doesn't return anything either:
authorize = async () => {
try {
const authState = await authorize(config);
console.log(authState);
} catch (error) {
console.log(error);
}
};
The only time I see any feedback is if I cancel before it is authorized. Then it says the user has cancelled but if it is successful I get no feedback after returning to the app except for the email from Coinbase saying it was successful.
ExpoKit?ExpoKitHi @whittlem - I couldn't reproduce this issue on the example app.
Could you try authenticating using the public IdentityServer config? This is to see if the issue is specific to Coinbase.
const config = {
issuer: 'https://demo.identityserver.io',
clientId: 'native.code',
redirectUrl: 'io.identityserver.demo:/oauthredirect',
scopes: ['openid', 'profile', 'email', 'offline_access']
}
I tried that initially but it didn't work. I can try again. I didn't know what to put or the "issuer".
I just followed the Coinbase developer guide:
https://developers.coinbase.com/docs/wallet/coinbase-connect/reference
So what would the public IdentityServer config look like for this?
const config = {
clientId: '<removed>',
redirectUrl: 'MyApp://oauth',
scopes: ['wallet:accounts:read'],
serviceConfiguration: {
authorizationEndpoint: 'https://www.coinbase.com/oauth/authorize',
tokenEndpoint: 'https://api.coinbase.com/oauth/token',
revocationEndpoint: 'https://api.coinbase.com/oauth/revoke'
}
};
Would it be?
const config = {
issuer: 'https://www.coinbase.com',
clientId: '<removed>',
redirectUrl: 'MyApp://oauth',
scopes: ['wallet:accounts:read']
};
It sounds like this Issue may be similar to mine:
https://github.com/FormidableLabs/react-native-app-auth/issues/293
Would it help if I created a temporary "bug fix" oauth application on Coinbase and provided the details? Then all you need to do is register for a free account and you should be able to re-create it.
I just wanted to mention again that the oauth authorize seems to work. It goes through the whole process and redirects back to the app without a problem. I also get an email from Coinbase to say that the application has been successfully associated with my account after logging in. The problem is your authorize function doesn't return anything at all. The only time I see any feedback at all is if I cancel the authorize before it has completed. Then I get a message to say the user has cancelled.
I've created you a temporary OAuth application in Coinbase.
ClientID:
dec2a79b0d9671bba8ca6c1b0b21fd4e1f49e456861669bc1eeaf4f19414b305
Redirect URIs:
RNAppAuth://oauth
Sample Authorize URL:
https://www.coinbase.com/oauth/authorize?client_id=dec2a79b0d9671bba8ca6c1b0b21fd4e1f49e456861669bc1eeaf4f19414b305&redirect_uri=RNAppAuth%3A%2F%2Foauth&response_type=code&scope=wallet%3Auser%3Aread
Verification deeplink:
RNAppAuth://verification
Scope restrictions:
wallet:transactions:send is limited $1.00/day per user
wallet:transactions:send:bypass-2fa is disabled
You should be able to re-create my issue with this and signing up for a free Coinbase account.
I need to get this working...
const config = {
clientId: 'dec2a79b0d9671bba8ca6c1b0b21fd4e1f49e456861669bc1eeaf4f19414b305',
redirectUrl: 'RNAppAuth://oauth',
scopes: ['wallet:accounts:read'],
serviceConfiguration: {
authorizationEndpoint: 'https://www.coinbase.com/oauth/authorize',
tokenEndpoint: 'https://api.coinbase.com/oauth/token',
revocationEndpoint: 'https://api.coinbase.com/oauth/revoke'
}
};
oauth() {
authorize(config)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
@kadikraman, if you want help fixing this I'm happy to help.
Thanks for creating the demo application, it helps a lot! I鈥檓 replying to let you know I will be looking into this issue as a priority, but I鈥檓 very busy this week, so I will do it Saturday/Sunday.
i have the same problem with my custom server :(
@kadikraman, while you are looking at this would you mind updating this as well?
warning " > [email protected]" has incorrect peer dependency "react-native@^0.50.3".
It is not an issue as such but nice to have no warnings :)
"react-native": "0.57.7"
Wow, that was a lot of hoops to jump through. I won't go into details, but did get to repro your error on our example app. I haven't quite been able to pinpoint the underlying cause at the moment, so I'll have to pick this up tomorrow, but my hunch is that it's a problem with the redirect uri, because I had to press the "authorize" button twice for the web view to close, and nothing got deep linked through to the app.
Thanks for the update and glad you managed to re-create the issue at least. I also have to click the Authorize twice. The strange thing is it actually works. Coinbase sends me an email to say my account was successfully linked to the app but your library doesn鈥檛 return anything. Hopefully you manage to crack this tomorrow. Much appreciated for the quick response on this. My deep link works. I've got my React Native app to recognise MyApp://oauth for example and redirect back to the app with no problem. So not convinced this is a deep links issue or maybe the data is trying to return on the first click of "Authorize" but the app isn't picking it up. The "authorize" function does actually return something but only if you cancel the oauth session. Then it says the user has cancelled. I think that is coming through on the catch of the promise.
@kadikraman btw this also happens for Dropbox. Only response I can ever get is the 'user cancelled' one. I can make a separate issue, but it seems like the fix for this would solve the dropbox case too.
UPDATE: To solve my error, I had to comment out OIDAuthorizationService.m line 113. It could have been a special case for us since we're using a redirect URL from our client that returns a URL scheme to go back to our app. Here's the dropbox request config in any case:
const config = {
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET',
redirectUrl: 'https://staging.client.com/dropbox_redirect',
scopes: [],
serviceConfiguration: {
authorizationEndpoint: 'https://www.dropbox.com/oauth2/authorize',
tokenEndpoint: `https://api.dropbox.com/oauth2/token`
},
useNonce: false,
usePKCE: false
}
where https://staging.client.com/dropbox_redirect redirects the mobile browser to com.ourclient.app which our ios project has as a registered url scheme.
@kadikraman How are you getting on? Any luck solving this?
Hi @whittlem - sorry I've been travelling for the past week, only just got back on this today.
Could you change the redirect URI in the example app you created to be anything other than RNAppAuth://oauth? For example, RNAppAuthExample://oauth. This is because RNAppAuth is the namespace of this library, so I won't be able to create an example app named RNAppAuth and install react-native-app-auth since there is a naming clash.
@kadikraman, thanks for the update.
I've made the change:
RNAppAuthExample://oauth
@kadikraman, did it help? Changing the deep link for you?
Hi @whittlem - I created my own app in the end. I think I'm missing something obvious. Changing the app name makes no difference (it was a silly suggestion actually now that I think about it).
I'm thinking perhaps we need to actually register a url scheme? (This is confusing to me since I've not had to do that for any other IDP for iOS). I know auth with iOS should be possible due to this issue. In the example config, their redirect url is uri://com.chaching.wallet 馃
@kadikraman, I don't think it is the deep link causing the issue. I have it configured correctly in Xcode and I successfully get redirected back to my app after authorization. The authorization actually works as I get an email from Coinbase to say it was successful. The issue I have is that your authorize() function doesn't return anything and without the token I can't carry on. The only time I get anything back from your authorize() function is if I cancel then I get a message saying the user has cancelled.
Just for interest sake Coinbase has this in their site:
https://developers.coinbase.com/docs/wallet/coinbase-connect/mobile
OAuth settings for mobile applications
When developing mobile applications, consider specifying the following settings. Implemented correctly, these tools can improve the user experience by reducing friction in OAuth flow.
Redirect URI
For mobile or desktop applications, you may not have a redirect URI. For these cases you can set the redirect_uri to a special value when registering a new OAuth2 application: urn:ietf:wg:oauth:2.0:oob. This value tells our servers to render a blank page with the authorization code in the URL and title of the page, which can be parsed by your application.
This method uses the same pattern that Google follows in their documentation. Here鈥檚 a great guide with sample code for both iOS and Android.
Verification deeplink
Both sign up and login within the OAuth2 flow requires the user to verify her device and/or email by opening a link that Coinbase sends in a verification email. To make it easier to guide the user back to the native mobile application, a special verifications deeplink can be specified as part of your OAuth application鈥檚 advanced settings. This link will be opened automatically on successful verification, achieving a seamless transition.
I did actually try a redirect url of "urn:ietf:wg:oauth:2.0:oob" but it just returns a blank page which I believe is expected for mobile apps. I couldn't get the app to catch it and return back to the app. Even with the white screen I still didn't get anything back from your authorize() function.
This seems so close to working. If I could just find out what token was issued this would be working perfectly. That is the problem and where I am stuck now.
Are you at least seeing the same thing as me in your lab setup? I take it authorize() isn't returning anything for you either? If you want me to make any changes to the API config in Coinbase let me know.
This is what I have in my Info.plist:

This works and successfully redirects me back to my app. You can confirm this by going to Safari and opening "RNAppAuthExample://oauth". Is the "URL identifier" correct? Should it maybe be "www.coinbase.com" or "api.coinbase.com"?
When you debug your authorize() function do you get anything back from Coinbase at all? You should see the token in the headers apparently.
@whittlem I was having the exact same issue and I'm using the same approach of having an HTML page redirect to a custom URI (such as foo://auth).
I just tried the update from @pbfrias17 answer and it works! Comment out OIDAuthorizationService.m line 113 and run it again, it should return now. The problem is here in line 113:
if (![self shouldHandleURL:URL]) {
return NO;
}
The problem is that the custom URI that the app receives through deep linking is not the same as the one it was configured with (the one starting with https), and this check returns NO.
Other than this ugly fix, I guess the alternative is to use Universal Links. It would be nice to see some mention of this in the docs because I think lots of people would try this approach before turning to Universal Links.
@mion, thanks a lot. I'm at least getting a response now after authorization.
The issue I have now is this:
Error: invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
at createErrorFromErrorData (NativeModules.js:155)
at NativeModules.js:104
at MessageQueue.__invokeCallback (MessageQueue.js:414)
at MessageQueue.js:127
at MessageQueue.__guard (MessageQueue.js:314)
at MessageQueue.invokeCallbackAndReturnFlushedQueue (MessageQueue.js:126)
at debuggerWorker.js:80
I'm using the Xcode emulator for development.
@kadikraman, any ideas? How can I pass the client information in the authorization request?
@oaramirez89 - didn't you auth with Coinbase using this library on iOS recently?
We're having some trouble redirecting back to the app - the authentication is successful and we get an email from Coinbase, but the webview does not seem to redirect back to the app, and the auth response is always empty.
Did you have to set the redirect uri as a particular string, or do anything in the XCode settings to get it to work? I can't seem to figure it out, I'd really appreciate your advice :)
Hi @kadikraman and @oaramirez89, the fix from @mion seemed to help a little. Well it swapped one issue for another. By commenting out the lines he mentioned it says authentication fails because of an unknown client. I assume the Xcode emulator is not passing a suitable client in the header. So maybe fixing either of these issues may get it working. Ideally not having to comment out the lines and use the library as is would be best. Could it be that this is the underlying issue? And by not commenting out the lines it just returns null instead of the error message?
@whittlem @kadikraman Here is the code I used to successfully connect to Coinbase with OAuth2. The redirect uri I used matched the product bundle identifier I had for my ios App in XCode: com.chaching.wallet.
The additional parameters I had to add to comply with an account restriction to limit sends. This code worked as of march of this year. I am no longer working in that app so I have no way of confirming if it still works today.
HTH
// base Coinbase config
const config = {
clientId: '< your client id >',
clientSecret: '< your secret >',
serviceConfiguration: {
authorizationEndpoint: 'https://www.coinbase.com/oauth/authorize',
tokenEndpoint: 'https://www.coinbase.com/oauth/token',
revocationEndpoint: 'https://www.coinbase.com/oauth/revoke',
},
redirectUrl: 'uri://com.chaching.wallet',
scopes: ['wallet:accounts:read', 'wallet:addresses:create', 'wallet:transactions:send'],
additionalParameters: {
account: 'all',
'meta[send_limit_amount]': '1',
'meta[send_limit_currency]': 'USD',
'meta[send_limit_period]': 'day',
},
}
...
try {
console.log('======= Calling Coinbase API =========')
authorize(config).then(res => {
console.log('====== Successful Coinbase API Call ========', res)
this.setState({ exchange, submitted: false })
this.setState({ apiKey: res.accessToken, submitted: false })
this.setState({ apiSecret: res.refreshToken, submitted: false })
}, (error) => {
console.log('==== Failure in OAuth2 initialization ====', error)
})
// result includes accessToken, accessTokenExpirationDate and refreshToken
} catch (error) {
console.log('==== Failure in OAuth2 initialization ====', error)
}
@oaramirez89, worked perfectly. Thanks so much.
Thanks @kadikraman and @mion as well.
Thank you for saving the day, @oaramirez89 馃槄 - I could have sworn I tried uri://app.id, but clearly not. I'm so glad this is finally resolved. Thanks for your persistence @whittlem - I'll add a config example for Coinbase for the future.
@kadikraman, just FYI the fix didn't have anything to with the redirect URI. I am still using RNAppAuthExample://oauth for example. I think adding the "clientSecret" to the config did the trick.
Haha, oh, no way 馃う鈥嶁檧 - it never occurred to me to try that, since it's not recommended for native apps (anything bundled into a native app is no longer secret) and I was expecting Coinbase to be a stickler to the rules. Thanks for pointing that out.
I had this issue with an Okta server -- it worked for my user, but someone else would get nothing in return. The cause ended up being that their user wasn't enabled for this app in particular.
Also, make sure that your callback URI is set correctly & consistently both in your config and in the Android config.
@whittlem I was having the exact same issue and I'm using the same approach of having an HTML page redirect to a custom URI (such as
foo://auth).I just tried the update from @pbfrias17 answer and it works! Comment out
OIDAuthorizationService.mline 113 and run it again, it should return now. The problem is here in line 113:if (![self shouldHandleURL:URL]) { return NO; }The problem is that the custom URI that the app receives through deep linking is not the same as the one it was configured with (the one starting with
https), and this check returns NO.Other than this ugly fix, I guess the alternative is to use Universal Links. It would be nice to see some mention of this in the docs because I think lots of people would try this approach before turning to Universal Links.
Actually, I was having the same problem as you with Stripe, and did the same URL forwarding. Stripe only accepts https redirect URIs. So, after I get redirected to my own website, the website redirects me to my deeplink including the data from the provider.
Stripe registered URI: https://domain.com/redirect?code=xxxxxx
At code level:
const config = {
redirectUrl: 'RNAppAuthExample://oauth ',
}
@kadikraman, I don't think it is the deep link causing the issue. I have it configured correctly in Xcode and I successfully get redirected back to my app after authorization. The authorization actually works as I get an email from Coinbase to say it was successful. The issue I have is that your authorize() function doesn't return anything and without the token I can't carry on. The only time I get anything back from your authorize() function is if I cancel then I get a message saying the user has cancelled.
Just for interest sake Coinbase has this in their site:
https://developers.coinbase.com/docs/wallet/coinbase-connect/mobileOAuth settings for mobile applications
When developing mobile applications, consider specifying the following settings. Implemented correctly, these tools can improve the user experience by reducing friction in OAuth flow.Redirect URI
For mobile or desktop applications, you may not have a redirect URI. For these cases you can set the redirect_uri to a special value when registering a new OAuth2 application: urn:ietf:wg:oauth:2.0:oob. This value tells our servers to render a blank page with the authorization code in the URL and title of the page, which can be parsed by your application.This method uses the same pattern that Google follows in their documentation. Here鈥檚 a great guide with sample code for both iOS and Android.
Verification deeplink
Both sign up and login within the OAuth2 flow requires the user to verify her device and/or email by opening a link that Coinbase sends in a verification email. To make it easier to guide the user back to the native mobile application, a special verifications deeplink can be specified as part of your OAuth application鈥檚 advanced settings. This link will be opened automatically on successful verification, achieving a seamless transition.I did actually try a redirect url of "urn:ietf:wg:oauth:2.0:oob" but it just returns a blank page which I believe is expected for mobile apps. I couldn't get the app to catch it and return back to the app. Even with the white screen I still didn't get anything back from your authorize() function.
This seems so close to working. If I could just find out what token was issued this would be working perfectly. That is the problem and where I am stuck now.
Are you at least seeing the same thing as me in your lab setup? I take it authorize() isn't returning anything for you either? If you want me to make any changes to the API config in Coinbase let me know.
I am using azure B2C credentials for login. Still, I didn't get any return value can u help me