I would like the following architecture (I've made up the product name for this example):
Web API 2 application running on one server http://api.prettypictures.com
MVC 5 client app running on another server http://www.webpics.com
I would like www.webpics.com client app to use the Pretty Pictures API to:
- Register new accounts with username and password
- Register new accounts with Facebook/Google/Twitter/Microsoft
- Log in
- Retrieve pictures
All of the above works except registering external accounts with Facebook, Google etc.
I cannot work out the correct flow to create an external account from a separate client user of the API.
I have studied most documents available on the authentication flow, like this:
I have read pretty much everything I can on the new Identity model in OWIN.
I've examined the SPA template in Visual Studio 2013. It demonstrates how to do most of what I need but only when the client and the API are on the same host; if I want multiple clients accessing my API and being able to let users sign up via Google etc. it doesn't work and as far as I can tell the OWIN authentication flow breaks.
Here is the flow so far:
- User browses to www.webpics.com/Login
- www.webpics.com calls api.prettypictures.com/Account/ExternalLogins (with a returnUrl set to go back to a callback at www.webpics.com) and displays the resulting links to the user
- The user clicks "Google"
- The browser redirects to api.prettypictures.com/Account/ExternalLogin with the name of the provider etc.
- The API's ExternalLogin action instantiates a challenge to google.com
- The browser is redirected to google.com
- The user enters their username and password (if they are not already logged in to google.com)
- google.com now presents the security clearance: "api.prettypictures.com" would like access to your email address, name, wife, children etc. Is this OK?
- User clicks "Yep" and is taken back to api.prettypictures.com/Account/ExternalLogin with a cookie that Google has set.
This is where I've got stuck. What is supposed to happen next is somehow the client app should be notified that the user has successfully authenticated with google.com and be given a single use access code to swap for an access token later on. The client app should have the opportunity, if necessary, to prompt the user for a username to associate with their google.com login.
I don't know how to facilitate this.
In fact at this point the browser ends up sat at the api.prettypictures.com/Account/ExternalLogin endpoint after the callback from Google. The API is signed in for Google but the client doesn't know how to deal with that. Should I pipe that cookie back to www.webpics.com?
In the SPA app, it is done via AJAX and google.com will return an token as a URL fragment and it all works nicely because it all sits on one domain. But that defies much of the point of having an "API" that multiple clients can fully use.
Help!