How to implement native auth with Spotify iOS SDK? I don't want to see popup window of Spotify login as it is currently implemented.
Or is it possible using Web API?
I look at the app called "SoundFocus" on App Store - their Spotify auth screen looks like native - I need to do the same. How to do it?
Thank you
At the moment fully native login is not supported with the SDK:s. SoundFocus is probably using an older API (like libSpotify). You should implement your own backend service (Authorization Code flow) as outlined in the documents here: https://developer.spotify.com/web-api/authorization-guide/
Authorization Code Flow
This method is suitable for long-running applications which the user logs into once. It provides an access token that can be refreshed. Since the token exchange involves sending your secret key, this should happen on a secure location, like a backend service, not from a client like a browser or mobile apps. This flow is described in RFC-6749.
Related
I'm building a mobile app (and possibly a website) that uses a REST API to handle all the logic.
That being said, the REST api itself should call a 3rd party REST API (the Spotify one) to handle the logic for the app/website.
So basically the user should sign in to my app/website using its Spotify account and my API should make calls to the Spotify Web Api to retrieve user data using its access token, and then send them back to the app/website.
Now I've spent quite some time studying Spotify guidelines about authentication here and it looks like the Authorization Code Flow should fit my use case.
I definitely need to call the /authorize endpoint to retrieve the code from my app since I need user interaction for that. After that, I do get back the **code** that I should exchange for an access_token and refresh_token.
But as I said, it's not the app itself the makes the calls to the Spotify API, but my API. So theoretically I should send the received code to my API and let him handled retrieving and refreshing the access_token and refresh_token.
So my question is if this makes sense? Is it ok to send the code from the app to my api?
Not sure if it's clear so I'll attach a diagram of what I'm intending of doing.
Also probably after receiving the code, I would send back my own token to the app to be used with each future request (somehow similar with what you would do when you handle authorization with Facebook or other socials)
Hmm - some assumptions below, but I would aim to use standard flows. Some solutions are not possible in a good way though.
BUSINESS SOLUTION
Are you trying to build an app that combines the user's Spotify data with your own data for the user?
ARCHITECTURE TO AIM FOR
Your own UIs and APIs should use tokens issued by you and not Spotify. Only use Spotify tokens when you need to access Spotify resources. This leads to simple and reliable code.
STANDARD OPTION 1
This is based on you being in control of data from multiple sources:
You should have your own login and token issuing system. UI first logs into your app, which enables it to call your API with a token.
When you want to access Spotify you need to redirect the user again. The user can then consent to you using Spotify resources in your app, after which your web / mobile UIs get a Spotify token and can call Spotify APIs.
STANDARD OPTION 2
This is based on allowing the user to sign in with a familiar credential, which works via a federated login:
User needs to login
Your app redirects to your Authorization Server
There is a second redirect to Spotify
User logs in at Spotify
Spotify posts a token to your Authorization Server
Your Authorization Server posts its own token to your mobile app
Meanwhile your Web API has its own connection to Spotify that uses the Client Credentials Flow.
DOUBLE HOPPING CODES / TOKENS
This is not insecure, but it will add a lot of complexity and is not standard. You would need to maintain some kind of API session with 2 types of token per user and access token expiry would be a horrible area.
MOBILE FLOW
For mobile apps you should use Authorization Code Flow (PKCE) - my blog posts have some stuff on messages and user experience.
I am building Angular app that should interact with Xero API. Xero doesn't provide any SDK for Typescript (https://developer.xero.com/documentation/libraries/overview), but Node JS SDK seems to be the most useful lib for my task. But I am in stuck in how to organize the workflow between my app and their https://github.com/XeroAPI/xero-node-oauth2-app . I mean - I'd like to have some advises from the person who has already made similar apps (Angular + Xero) on following questions:
1) in this guide https://developer.xero.com/documentation/oauth2/auth-flow they say that user should open the page with URL like https://login.xero.com/identity/connect/authorize?... - but is there any way to make user log in without UI? If not -
2) how this process can be made in my case? In my Angular app I can make a button 'Log in to Xero' that will open new window:
window.open(xeroUrl, 'xeroAuth', 'location=yes,height=770,width=620,scrollbars=yes,status=yes');
where User log in, provide access to his organisation. The session tokens are created on the backend. But what next? How can I pass those tokens to my Angular app from that new window and then use them to make calls to Xero API?
3) Is the way to open new window for loggin in to Xero suitable for this case or maybe there is a better way to log in to Xero and get session tokens?
Thanks in advance for help.
Unfortunately, SPAs are not compatible with the Xero API.
You'll need a web server to manage your local session (OAuth flow, storage of Xero API tokens), and for your interactions with the Xero API.
While SPAs are a tempting option (they are convenient from a deployment point of view), there are changes coming to how browsers handle cross-site cookies, which break how SPAs perform session management.
I'd suggest reading https://leastprivilege.com/2020/03/31/spas-are-dead/ for more information and a discussion of the implications. The authors of the article created OIDC Client JS which is a great library for doing PKCE-based SPA auth in the browser, though it's only useful for same-domain applications now thanks to the impending browser cookie changes.
Further to this, the Xero API does not support CORS, so even once you complete the OAuth flow, the browser would be prevented from performing API requests from your Angular SPA.
To answer the specific questions:
1) The user will need to log in to Xero and grant consent for your app the first time they use your application. If you're storing server-side refresh tokens after the initial consent, your user will only need to log in to your local session, either via Xero SSO or another mechanism (user/password).
2) To create the initial Authorisation Request, it's best to use the node.js starter app. It will manage the OAuth redirect flow for you (it uses the excellent openid-client open source package for this).
I am developing a mobile application and am using React Native with a NodeJS / MongoDB API Backend.
I would like to add social authentication (Google/Facebook) to my application.
It is also important to me that the social authentication happens as a Native Login flow and not browser based (i.e. the user is not redirected to the browser to enter his/her credentials).
I also want to have some token returned whenever the user authenticates with either Google or Facebook so that I can use the token to call my API, verify that the token is correct and return user specific resources.
Most examples that I found use Firebase but I prefer not using Firebase since I am already using MongoDB. Other examples implement a WebView thus the user is redirected to the corresponding social provider via the browser and I also don't want that since I want to provide a Native experience.
I am also thinking to try and use one of the following libraries: https://github.com/FormidableLabs/react-native-app-auth or https://github.com/fullstackreact/react-native-oauth to implement this.
I am looking for any help/suggestions on how to implement this.
For Facebook, use react-native-fbsdk.
For Google, use react-native-google-signin.
Both do not redirect to browsers for login and have tokens should you need to use them.
I have a Web application that currently uses OAuth2 to authenticate users using their Google accounts. The flow is quite standard: the user logs in to Google, the web app gets a callback, retrieves the user identity and stores it in the session.
Now I need to create an accompanying Chrome extension. This extension needs to access the web app underneath, so it needs to authenticate against this app. I configured my extension using the official documentation, but during experiments, I realized this is not what I need. Since it uses the OAuth2 implicit flow, it doesn't return a token that could be validated on the server side. This flow is suitable only for using Google APIs on the client side, which is not my use case. This documentation (and pretty much everything else I found on the Web) focuses on two possible cases:
We want to access Google APIs on the extension side (chrome.identity.getAuthToken()).
We want to authenticate using an alternative OAuth2 service (chrome.identity.launchWebAuthFlow()).
However, in my case, I'd like to authenticate users using Google accounts, but process the token on the server side of my Web app. I could use option 2 here, but it just doesn't "feel right" to me to create my own "non-Google authentication service" that is just a wrapper over Google authentication service, only to be able to authenticate on the server side.
Is option 2 really the only way to go, or is there any simpler way?
I also saw someone recommending using the tokeninfo endpoint to validate the token, but I find it hard to make sure that this is indeed an "official" and secure way of doing this.
To retrieve an access token that you can use on both parts of your app, the extension and the server, you should request a Google Cross-Client Access Token. This allows you to register your two apps (two client IDs) in a single project and share an access token.
This is described and discussed by Google here:
Docs: Google Identity Platform: Cross-client Identity
Video: Google Drive SDK: Cross-client authorization
The rough steps are:
You will need two clientIds, one for your extension and another for your server app
Add both clientIds to a single project
Retrieve the cross-client access token from your extension
Send it to your server via HTTPS
To do this in Chrome, it looks like you would call chrome.identity.getAuthToken() with a callback function that sends the token to your web app.
The reference says the following on chrome.identity.getAuthToken():
chrome.identity.getAuthToken(object details, function callback)
Gets an OAuth2 access token using the client ID and scopes specified in the oauth2 section of manifest.json.
and that it can take a callback function as specified as:
Called with an OAuth2 access token as specified by the manifest, or undefined if there was an error.
If you specify the callback parameter, it should be a function that looks like this:
function(string token) {...};
Ref: method-getAuthToken
I built an AngularJS application calling some REST API's belonging to my own backend (using Play! 2.2).
I'm using Facebook OAuth client in order to authenticate my users.
As being a Javascript App, my Facebook App Token cannot be "hidden".
Thus, anybody who picked up the Facebook App Token, by just reading the Javascript code could grab a user access token in a "legally" way and therefore use my REST API's.
How could I prevent it?
What is the best practice?
One way would be, I think, to use the server side Facebook's OAuth mechanism, rather than the Facebook Javascript SDK.
In this case, the Facebook app secret would be stored on my server and unreachable from the outside.
But as being a Single Page Application on client-side, I really want to avoid page redirection and benefit of the "popup" feature that comes with Facebook Javascript SDK.
There are a couple of things you can do.
Using the server side ("code") OAuth flow for facebook auth is much more secure. You can still avoid redirects by opening your own popup to initiate the login sequence, similar to what the Facebook JS does (only it goes to your server first).
Enabling HTTPS on your application is usually a good practice...
And if you're worried about cross site forgeries you can implement something like an anti forgery state token. See http://blog.codinghorror.com/preventing-csrf-and-xsrf-attacks/ and also google's instructions here https://developers.google.com/accounts/docs/OAuth2Login#createxsrftoken .