Single Authentication Scala (PlayFramework) + mobile app - scala

There is a mobile application that requests a phone number and sends a code from SMS during authentication.
Now I have a request sent to the backend with a phone number that generates a request to the SMS service. The service issues a token, which is sent when the code is confirmed from SMS. If success, I issue a token that lives for a certain time.
It is necessary to do authentication on Scala +PlayFramework, for example, as in Whats'up, telegram, where the token has an unlimited lifetime.
I have been looking for information for a long time, which libraries to implement this, but I have not found a solution, I will be grateful to the advice.

Related

Stop api abuse before user is authenticated

We have an Android app. Users need to login using sms based OTP before app can be used.
Our request for OTP is public API. Attackers have started to abuse this API. 10x more API calls as compared to actual users.
What are the different ways this can be prevented? Solution should work at scale with response time and server resources should not get impacted.
You could do some server-side throttling by IP address and/or telephone number. But a persistent abuser could have blocks of numbers and IPs available.
The best solution is to have your app sign the payloads you send to your backend. If an unsigned or incorrectly signed payload comes in, don't send an OTP.
For iOS there's attestation, for Android there's Play Integrity. These API's allow you to verify that a call to your backend originated from a genuine app.

RESTful registration with activation email

I'm working on creating a REST API and one feature is to allow users to register. The general flow is the following:
The user specifies his email and password using the client application (SPA application) and presses the submit button.
A request to the API is made. The API adds the user to the database, generates a verification token and sends an email to the user.
The user verifies his email and clicks a confirmation link.
The API marks the user account as verified.
My question is regarding the confirmation link.
Should the link point to the client SPA application? In this case, the client application will make a POST request to the API with the verification token and the user email.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Another approach would be for the link to go to an endpoint defined by the API. In this case a GET request will be made with the user email and verification token and the API will set the account as verified and inform the user that his account is now active.
I have read that this approach doesn't conform to the REST principles because a GET request should never change the state of a resource. In this case, the user resource will be modified.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Thanks!
Should the link point to the client SPA application?
If your 'Client SPA application' is the sole frontend for end-users, then yes: it should point there. Some people deploy a separate oauth2 / authentication server but that doesn't sound like it's the case here.
The client application will make a POST request to the API with the verification token and the user email.
The token should be enough. I'd avoid sending email addresses through urls.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Both seem like really valid designs. If you want the API to be completely unaware of the front-end and support a multitude of frontends, it would make sense to me that the client sends their own endpoints. There is a security concern though, you don't want arbitrary clients to register arbitrary urls.
If you're just building a single frontend, I don't see a problem with the API knowing the activation url. It also sounds like it would be easy to change if your requirements change later.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Ultimately it doesn't really matter that much. Neither approach sounds like you're really painting yourself into a corner. Either you have a standard endpoint that uses a javascript HTTP request to activate a user, or you have a separate endpoint that redirects a user after activation. Both will work.

building a service with an android app, an iOS app, and an API backend, all of which access the Facebook Graph API

i'm trying to build a server with a rest api and database.
it has ios and android clients, where you can log in with facebook.
the server can receive the access token that the clients get when they log in for the first time, and send it to the server. the server stores it in the database.
now the server can make graph api calls on the clients behalf.
but here's my question:
the next time the client asks the server to do something on it's behalf, what info must it send so that the server knows who the client is? is it just the access token again?
thank you
Just the access token is enough to uniquely identify the user and the app.
You could try it by hitting graph.facebook.com/v2.10/me?fields=id&access_token=... with different tokens to check which user it is and whether the token is still valid.
Off topic, but since you're already using the server as the middle-man for your requests, I suggest using the code flow instead of token flow for added security: https://developers.facebook.com/docs/facebook-login/security#appsecret

Get messages from Gmail via HTTPS GET call

I'm working on an iOS application and what I'd like to do is have the app ping one universal Gmail account to check for the most recent email.
I went through the guide from Google at https://developers.google.com/gmail/api/quickstart/ios?ver=swift, but the result did not work. After some googling, it appears that some functionality may have been changed, but they haven't updated their documentation yet.
Is there a way to send credentials via https to Gmail and get email messages back? I have an OAuth key via the Gmail API manager, but when I pass it as "access_token", the response says "Login Required".
AFAIK, an error response "Login Required" can be encountered if you try to list the buckets for a project that do not provide an authorization header.
If we check Users.messages: get, it's noted that it requires authorization.
For this, you may want to check Authorizing Your App with Gmail wherein you will find these basic authorization pattern:
During development, register the application in the Google API Console.
When the app launches, request that the user grant access to data in their Google account.
If the user consents, your application requests and receives credentials to access the Gmail API.
Refresh the credentials (if necessary).
Furthermore, if your application needs to access Google APIs on behalf of the user, you should use server-side flow. Please see Implementing Server-Side Authorization for more information.
Sometime back I was involved in writing a sample application to access email from gmail but using C++ on windows. The code is at https://github.com/Panchatcharam/simple_gmail_api. I was able to successfully get emails.

OAuth - what to store on disk

TL;DR When using google oauth on desktop app, what to save on disk to avoid repeated sign in? Save the google user id? or the token? or an session id?
I'm creating an little desktop app, whitch must authenticate to my REST API server. I'm using google oauth2 for that.
The idea is, that when the desktop app will be authentivated, it generates some data that will be send to my server. The server will store the data with the google user id received from https://www.googleapis.com/userinfo/v2/me.
On the first run of the desktop app, it will open the default browser, with and url for my server and start an local http server. then:
my server will redirect the browser to google (with the clientid, secret, etc.)
user logs in and it will be redirected back to the server with the oauth code
server uses the code to get the token, and then the user profile and stores the token and the profile in db, then redirects the browser to localhost with an paramerer
the desktop app catches the parameter and stores it in an file on the disk
next time the desktop app will start it only reads the file for the parameter to send the generated data with it to my server
my question is: what the parameter should be? the google user id? the oauth token? an generated session id for this desktop app? or something else?
when it will be the google user id, it can conveniently sent the data with the user id and the rest server will just store it in db as is. but I don't think it's safe
when it will be the token, the rest server has to with every request also get the user profile from google with the token. and imho sending the token with every request isn't safe either
generating an session id means to store it with the user and the token on the server and the desktop app will just store it and send it with every request. but I don't know if it's safe to do that
As it's normally the case in software development you have a couple of options depending on requirements.
The mandatory requirement is that your client (desktop) application needs to send something to your REST API so that the API can perform up to two decisions:
Decide who the user is.
Decide if the user is authorized to perform the currently requested action.
The second step may not be applicable if all authenticated users have access to exactly the same set of actions so I'll cover both scenarios.
Also note that, for the first step, sending the Google user ID is not a valid option as that information can be obtained by other parties and does not ensure that the user did authenticate to use your application.
Option 1 - Authentication without fine-grained authorization
Either always sending the id_token or exchanging that token with your custom session identifier both meet the previous requirement, because the id_token contains an audience that clearly indicates the user authenticated to use your application and the session identifier is generated by your application so it can also ensure that. The requests to your API need to use HTTPS, otherwise it will be too easy for the token or session ID to be captured by an attacker.
If you go with the id_token alternative you need to take in consideration that the token will expire; for this, a few options again:
repeat the authentication process another time; if the user still has a session it will indeed be quicker, but you still have to open a browser, local server and repeat the whole steps.
request offline_access when doing the first authentication.
With the last option you should get a refresh token that would allow for your application to have a way to identify the user even after the first id_token expires. I say should, because Google seems to do things a bit different than the specification, for example, the way to obtain the refresh token is by providing access_type=offline instead of the offline_access from OpenID Connect.
Personally, I would go with the session identifier as you'll have more control over lifetime and it may also be simpler.
Option 2 - Authentication + fine-grained authorization
If you need a fine-grained authorization system for your REST API then the best approach would be to authenticate your users with Google, but then have an OAuth 2.0 compliant authorization server that would issue access tokens specific for your API.
For the authorization server implementation, you could either:
Implement it yourself or leverage open source components
⤷ may be time consuming, complex and mitigation of security risks would all fall on you
Use a third-party OAuth 2.0 as a servive authorization provider like Auth0
⤷ easy to get started, depending on amount of usage (the free plan on Auth0 goes up to 7000 users) it will cost you money instead of time
Disclosure: I work at Auth0.
There should be no problem sending the access_token with every request since they are created for that purpose and are thus short lived. You can use the Google Authorization Server endpoint to verify a token instead of using it to do a request for a users profile.
If you're only relying on Google for authentication, here's how your workflow can look:
the client (desktop application, in your case) retrieves the
Google id_token following the user's log in, and then sends it to
the server
the server validates the integrity of said token and extracts the user's profile data; this could mean a simple GET on Google's endpoint to verify this token: https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
On subsequent requests, nothing should change really, except that the user's login process will be automated (since he's given permissions & all), and thus much faster. #danielx is right, there's no problem with sending the token each and every time.