How should I create my API for mobile applications (Needs Authentication) - php

Background
So I've been researching quite a bit for the past week about API's and have been reading about concepts and also programming one.
Currently I have a website which is programmed in PHP using a popular framework called Laravel. The website has a user database and users are able to log into the dashboard on my website, everything works as I want it to for my website side.
Now for the next project of my business i'm focusing on creating my mobile applications (IOS & Andriod).What I need for these mobile applications is being able to login through the application UI (not being redirected to my site with a callback URL) so they are able to view and manage the dashboard.
The method of authentication and authorization that i want to use for my application will go something like
Client asks user to login through UI
User enters credentials
Client sends a request to login to the API
The API checks if the credentials are correct
API creates a token which is stored in token database linked to user ID
API returns 200 OK with a json response or something like this
{ "token" : "OLS25usJIay81hdy81", "expiry" : 3/06/2016 14:00}
Client remembers token and expiry
Whenever a user/client makes a request such as api/v1/mystuff/orders it sends the token with the request(probably through the http headers?)
API verifies token, gets user ID and finds users orders
Questions
I know this is one hell a question and i'm not asking you people to program my entire software haha but what I need to know is
What should I use to create the API (needs to be PHP, and preferably laravel integrated)
What are some good resources to help me program my API
Is there any suggestions/changes you'd recommend?
Requirements
Username/Password authentication
Token Authorization
Login through app UI (Not on my website with a callback)
Notes
My website has a SSL cert.

Laravel is definitely a very good choice to create your API and your plan for authentication and authorization is pretty solid.
I could recommend for you to use the JSON token authentication package for Laravel https://github.com/tymondesigns/jwt-auth
You can see some tutorials here:
https://scotch.io/tutorials/token-based-authentication-for-angularjs-and-laravel-apps
https://www.sitepoint.com/how-to-build-an-api-only-jwt-powered-laravel-app/
I would also recommend this API package https://github.com/dingo/api which will save you a lot of work.
If you need some help you could watch this series https://laracasts.com/series/incremental-api-development from Laracast, which requires a subscription, but it's more than worth it.

Related

Creating a Multi Tenancy / Saas and having trouble desiging the database for users

I'm building an SAAS with a single database. Tenant in this case is called site.
I want to achieve what Stackexchange does where it has a global login as well as a stackoverflow/softwareengineering/etc login. I'm not sure how to store users. A user can have many sites and sites can have many users. The problem with designing a JoinTable is that the user roles are stored in the User table (im using Symfony3.4). I want separate roles per site/tenant.
Another problem I'm trying to figure out is how to go about logging in. I'm using oAuth2 and to login in I sinply call {{url}}/oauth/v2/token?grant_type=password&client_id=client_id&client_secret=client_secret&username=admin&password=pass. How should I make the user log in to a specific tenant/site? Do I add site_id to the query parameters?
Thanks for reading.
This question is very broad, so I'll take a stab at it.
If you are building out a network of sites, each site would ideally have it's own database. This will ensure sandboxing and the ability to easily migrate a site to it's own infrastructure if needed due to scaling or security concerns.
When dealing with user authentication, it sounds like you'll want a single secure user store that acts as the oauth2 server and each of the sites act as a Oauth client. You'll want to use the Authorization Code flow grant type in OAuth.
Essentially, a user visits Site A. Site A sees they are not logged in via the site's session. It redirects to your OAuth server which shows a login (think of the google login). Since Site A also passed in a callback url, once you've signed in, the OAuth server knows where to redirect the user, along with the valid token information. Then Site A takes that token and exchanges it for an access token on the server-side so now you've got authentication data on Site A.
If you are going to implement your own OAuth handshaking, you should utilize an existing server/client library. For PHP, you can look at the League OAuth server library, or use Laravel Passport, if you're using Laravel. There are other similar packages for other frameworks out there.

OAuth v.s my custom token based implementation

I am writing backend for a mobile app where the login info (user), details of the app and everything used in the mobile app will be on the server side.
That's how I have written the app flow:
The created users are saved on the server side via registration API
The newly created users send credentials and after authentication, I generate a dynamic token which is shared with the user for rest of the API calls
For every other call that a user makes, the token is authenticated and then the response is generated.
Each login generates a new token so at a time the same user won't be able to use the same account on 2 different mobiles. Since on valid login, a new token will be generated for API usage.
Whole of the communication takes place over SSL so everything is already encrypted. I want to know the security threats that would be saved by OUATH 2 in this scenario.
P.S Please write your thoughts in comments if you down-vote this question. Will highly appreciate it.

Login with Google, Facebook, etc, with own API

I have a problem to find the right way of implementing a login service.
First my environment:
An Android or IOS APP
My own web-api in PHP
Now the users have to login to get specific data from the api. So I have to check if the user is logged in with the API.
First i thought I could do this with JWT (JSON Web Token). But users with existing Google or Facebook account should also login to my side.
Is there a way to implement the login in PHP (the API site)? The most examples to login with Google or Facebook are simple Websites and not an APP with API.
How could I implement this login system?
Some time ago I thougt I could use GIT (Google Identity Toolkit). But now they switch to firebase and the website only contains examples for Webapps and Android/IOS.
Is there a common technique to do a login system like mine?
Do I have to implement OAuth2?
Oh. Besides the Google/Facebook login, there sould be a way to login with email and password.
I'm a little bit confused. It can not be, that I'm the only one with this problem. Or do I am a blockhead?
Yes, it is posible and it is well documented on the API's page.
For Facebook login, you can check this link.
For the Google's case, you should check this link
Side note: I know that I should quote the relevant parts of the link, but there are too much steps to follow, specially on the Google's case, so I haven't done it to avoid a huge block of quotes.
Solution:
Implement the Login in the Android- or IOS-App and get there the access token. Now send this token to the API. There you can check it and to everything you want with the Facebook-/Google-API.

REST API backend for mobile application (android/iOS)

I am developing a backend for mobile app. I have developed a user authentication module where, the app will be sending the username and password as basic auth and if the user is authenticated I will sent back a jwt token which can be used in the rest of the requests.
On the client side, once after a user is logged in, the app shows him a feeds screen which contains some data.
Now do I need to seperate these two APIs? Like once a user is logged in successfully, he will be sent back the jwt token and well some user details. Should I sent the data which is required for the dashboard screen as well as a response for login? In that the case the app will get datas in a single api request (login) and doest have to make another call to my API.
Is this a right approach?
Ideally it should be kept seperately but I think that depends. If making that single request is (and will ever be) the only thing the application does, I see no reason for making 2 requests. You can simplify things by making just 1 request.
But, if your application is going to be extended or if its already got other features i think it is best to keep them seperate. Since then you'll have more flexibility with your application.
Yes ,You should separate those two authentication and dashboard REST API as-
It could be possible that there should be more client app using your Rest API in future and they may not require dashboard data.However you can have mechanism to share user detail in authentication API itself as you are anyway authenticating user .However share access token in authentication api along with it's expiration timestamp .Some of Client app which are using your REST API might have use case of autologout from app based on accesstoken get expire.In such case expiration time would help.

Implementing OAuth 2.0 authentication with a Laravel API

I'm currently building a web application which is an AngularJS frontend that communicates with a RESTful API built using Laravel. I'm making good progress, but finding it hard to get my head around how to handle user authentication.
I've been advised that I should be using OAuth for authentication, and I've decided to use it seen as it could be a learning experience for me as well. The package I'm using to handle this is oauth2-server-laravel.
The basic user story is that users can register their username/password combination for the application, and they then log into the application with that same username and password. They're only authenticated by their username and password, and not by any client secret. After login, they should be given an access token which will be send along with every future request to authenticate them on different API endpoints.
The OAuth2 library has a "password flow" grant type which seems to be what I need, however it also takes client_id and client_secret parameters, which I don't want. The request URI is something like this:
POST https://www.example.com/oauth/access_token?
grant_type=password&
client_id=the_client_id&
client_secret=the_client_secret&
username=the_username&
password=the_password&
scope=scope1,scope2&
state=123456789
But what I want is just:
POST https://www.example.com/oauth/access_token?
grant_type=password&
username=the_username&
password=the_password
How am I meant to provide a client ID and secret of a user that has yet to authenticate?
Is there a different grant I can be using, or is what I want to achieve just not suited for OAuth at all?
Take into account, that client id and client secret aren't parameters that you have to force your end-user to pass. They are static and defined in/for your client app (angular app in this case).
All you need to do is to create a record for your main app in oauth_clients table, and create a scope with full access in oauth_scopes table, and send this values when requesting token.
And that's all in fact.
Also, you may want to consider using implicit grant flow in case of building js-only application, because storing client secret and refresh token in a js app is insecure. Using implicit grant in a final product may look like login window on soundcloud and is more secure as the token is obtained server-side without exposing client secret.
Another way to go, if you still want to use password flow is creating a proxy for refreshing tokens. Proxy can hide your refresh token in encrypted http-only cookie, and your js-app don't ask your api for new token, but the proxy instead. Proxy reads refresh token from encrypted cookie, asks the api for new token and returns it. So the refresh token is never exposed. If you set token ttl for an hour let's say, then stealing a token would be quite "pointless*" in case of a normal application, and stealing refresh token would be "impossible*".
*Of course if someone really want he probably could hack it any way.
And yeah, i know this all looks a bit hacky - modal windows for logging in, proxy etc. But also searching on this topic i couldn't find any better and more elegant way of doing it. I think that's still a lack that all js-apps have to deal with if you want a token based authentication.
You are missing something with the OAuth specification. The client_id and client_secret are really important when asking for an access token when using the password method of OAuth v2. In fact, they are important for every method that gives you an access token. They identify the application or the server that has perform the request.
For example, let's say you have your API, 2 mobile applications and another server that do some tasks with your API. You will create 3 clients with their own client_id and client_secret. If your application has various access levels (they are called scopes in OAuth v2), the client_id corresponding to the other server will be able to call functions of your API that require the scope admin whereas your mobile application will only be able to call functions of your API that require the basic scope if you have defined scopes like this.
If your API grows up in the future, this is really essential. Another example, let's imagine you have given an API key (a pair client_id and client_secret) to one of your friend and he has build a nice mobile app with your API. If one day he starts doing naughty things with your API, you can't stop him very easily. Whereas you could have just removed his key pair if you had followed OAuth v2 principles.
OAuth v2 is not an easy thing to understand, take the time to read specifications and good tutorials before developing your API.
Some useful links :
The official RFC : https://www.rfc-editor.org/rfc/rfc6749
A tutorial on Tutsplus : http://code.tutsplus.com/articles/oauth-20-the-good-the-bad-the-ugly--net-33216
Just to add a bit to plunntic's excellent answer: remember "client" is not related to "user", so when I use a password flow I just define the client_id and client_secret as constants on the AngularJS app to tell the api backend: hey, this is the browser app that is being used to request a token.

Categories