Ruby on Rails request in background - ruby-on-rails

In my Ruby on Rails app, a user can grant me permission to tweet on their behalf, so they can send prefilled tweets from the application. This is the flow:
request to my server
server request to twitter server
based on the response of twitter, my users gets a response.
The request to twitter blocks my app. I use ActiveJob with resque for other communication with 3rd party applications and e-mail, but in this case I want to give the user response based on the twitter server response.
Is it possible to somehow do?:
request to my server
server request to twitter server
put this in wait so my server can serve other requests
get notified on twitter server response and send response to my user
It is not a problem that my user sending the tweet has to wait. I just do not want other users to wait on that.

One solution is to use ActiveJob and rescue to request from twitter and when twitter responds, you can use a realtime engine to respond back to the user.
Another solution is to use a server that supports multithreading (puma, rainbows!..).
I personally think that I would use a realtime service to solve this problem. Although it adds some overhead but on the long run it will help sustain a higher number of concurrent users.

Related

Custom authenticator for 2FA with lighttpd

I have a web application which currently uses lighttpd with mod_auth and the htdigest method for authentication. I want to expand the web apps functionality to allow for 2FA. If I understand correctly, what happens for htdigest authentication is the following:
The browser requests a website from the server
The server responds with "authentication required"
The browser shows the user a window asking for username/password and sends this information to the server
The server serves the webpage
If I understand correctly, the server caches this auth info and automatically sends it for following requests.
Now, I want to add 2FA. I found out that I can use fastcgi to build a custom authorizer. Can I use this to do 2FA? How can I ask the browser to provide the user with a possibility to enter the OTP? It's no use to cache the OTP and send it with every request, so I guess I need to store a session token or something which the browser should send with every following request?

Am I doing this whole API, client app, Oauth/OpenId Connect thing right?

I have some programming experience, but only with PHP and Java enterprise systems. But now I have some ideas about a web app in my new job. Since I am new at this, I would like to share how I have done the whole API in a server, browser app and authentication with Google’s OpenID Connect (I read a lot about Oauth and OpenID Connect, most helpful source was this: https://developers.google.com/identity/protocols/OpenIDConnect).
Server: Laravel - hxxps://coolapp-api.mycompany.com
Client: Angular - hxxps://coolapp.mycompany.com
TL;DR version:
1) User goes to hxxps://coolapp.mycompany.com, gets an Angular app login page. Types in their email, clicks “Sign in with Google”;
2) The app sends the email to hxxps://coolapp-api.mycompany.com/api/sign-in. The server redirects the user to hxxps://accounts.google.com/o/oauth2/auth with all the needed parameters;
3) The user logs in to their Google account, gives my app permission if it’s their first time, and Google redirects them to my server at hxxps://coolapp-api.mycompany.com/sign-in/google/callback. The server checks everything, and if it’s all correct, it creates a JWT token and send a redirect to the client app at hxxps://coolapp.mycompany.com/login/callback?token=JWT-TOKEN
4) The client app gets the token, stores it in local storage, and sends it to the server with every API call
More detailed version:
1) User goes to hxxps://coolapp.mycompany.com, gets an Angular app login page. Types in their email, clicks “Sign in with Google”;
2) The app sends the email to hxxps://coolapp-api.mycompany.com/api/sign-in. The server creates a state token and stores it in cache, associated with the email received. Then the server creates Google’s oauth URL and sends it to the client in the response body. I tried to do it with a HTTP redirect, but Google’s server was responding with an CORS error. The Angular app reads Google’s url from the response and goes there.
3) The user logs in to their Google account, gives my app permission if it’s their first time, and Google redirects them to my server at hxxps://coolapp-api.mycompany.com/sign-in/google/callback?code=AUTHCODE&otherstuff. The server sends the code it received (and all the other needed parameters) to hxxps://accounts.google.com/o/oauth2/token. It receives a id_token with that user’s email and basic info. This app is not public, so I don’t want anyone with a Google Account logging in, only the clients whose emails I added to the server database. So now the server checks if the user’s email in the token is in the database. If it’s not, it sends the user a HTTP 401 - Unauthorized. Then the server checks the state token in it’s cache associated with the email received. If it’s equal to the one received with Google’s redirect, then the server creates another JWT token, but now signed by my server. Finally, it sends a HTTP redirect to hxxps://coolapp.mycompany.com/login/callback?token=JWT-TOKEN with the new token.
4) The client app gets the token, stores it in local storage, and sends it to the server with every API call
Some comments:
Everything is HTTPS;
I added the strictest CSP policies I could to my Laravel server and Angular client;
Currently the app only supports Google’s sign in, while it is in development. Later on I’ll add more.
I made that my server only checks if the user’s email is in the database after they logged in with google because I like that idea that a non-authorized user should have no information about anything. If I made that check before it, during the first round trip, anyone could type an email and discover if that email has an account in my system;
On the last step, when my server sends the JWT token to my client app, I tried sending the token within a cookie, but since my API and my client app have different domains, my client app couldn't read the token. Sending it in the url was the only solution I could find. I tried logging in a popular app that uses Oauth and they did it this way too.
So my question is:
Am I doing something wrong, unsecure, weird?
Thank you all very much
1) Entering an email address every time a user wants to log in is tedious. And it's not needed if the user is already logged in at Google. The user should just click the "Log in with Google" button and get logged in without entering anything. The state parameter can be a random string - not related to the user's email in any way.
2) If you want your backend to process the redirect from Google (using the auth code flow - the backend has the client role in OAuth2 terms), the backend should also initiate a redirect to Google - not by sending data containing the redirect URL. To achieve it, after clicking the "Log in with Google" button, perform a whole page navigation (instead of an XHR request) to /api/sign-in and if the backend returns HTTP 302, the browser will correctly redirect to Google.
3) You should perform request validation (the state parameter) before getting tokens and checking whether the user exist.
On error (access denied), you can consider redirecting the user to an error page with error details instead of returning HTTP 401, since the HTTP code will cause a generic error screen to be displayed to the user. If you want to keep using HTTP codes, I think HTTP 403 Forbidden would be more appropriate.
4) Consider using sessionStorage instead of the localStorage. The sessionStorage gets cleared after closing a browser/tab and it's not shared among tabs. It makes it safer and it allows users to use different identity in different browser tabs.
The tokens your backend issues, is their validity time limited? Is the user required to get a new token after some (short) time period? If not, valid token vales may stay in the localStorage and browser's page history, which can be a security problem.
You can consider using your own OAuth2 auth server (such as RedHat Keycloak) which would accept Google (and later some other providers) for authentication and it would also issue access tokens accepted by your backend.

Swift POST or GET request for user authentication iOS Swift

I was wondering if there are any advantages/disadvantages in using POST/GET method in Swift 2 to send password and username to the web server in order to authenticate the user. I am working on the iPhone application that fetches data from the web. The request passes the parameters to the URL and server sends data back. I modeled the current application with Enums defining a different endpoints for each request and it would be really easy for me to model Login the same way. However, I am not sure if that is the right direction.
So essentially GET is used to retrieve remote data, and POST is used to add/update remote data.
For security reasons, it does not make any difference. Just be sure that your connection is secured with an https certificate, and do not allow http connections.

iOS Sending Firebase Registration Token to My App Server

I currently have a functional iOS application (with react) and an app server using nodejs. So far, I am able to register with Firebase Messaging and console log my registration token through the AppDelegate.m file. And from my server, I can send my app a notification on a certain device with a POST method. However, in order to do that, I have to copy my registration token from the consolelog and paste it in the post request. Which is pointless because the token can change at any time.
I am still fairly new to this and I cannot find any examples of people sending their registration token to their app server. In all of the documentation it is always just a comment like "//If necessary send the token to your app server" with no explanation on how to go about it.
I just want to send the registration token to my server every time it refreshes so I can save it, and then send downstream messages to certain devices using their latest tokens. How do I get the Firebase token from my Obj-C AppDelegate file to my javascript server side? Can anyone help me out? Or show me an example?
You are on the right track, your app server will need an endpoint (say /register) that will let you make an http request posting your token to your app server.

Handling cookies with Flex for Authentication

I'm using Flex 4(beta2) with Ruby on Rails 2.3.5 and using RubyAMF to transfer data back and forth between Flex and server.
I set up Authlogic on the Rails side for authentication.
I wasn't sure what's the best method to handle user sessions. I know this is done automatically with Rails by sending session id with cookie which Rails use to authenticate the user.
What do you suggest the best way to do this with Flex?
I thought of couple of options:
1. Manually fetching the cookie from the browser and then figuring our a way to send that to the server with every request I send.
2. Handling sessions expiration and flow on Flex side by manually expiring the session
Do you have other suggestion or recommendation?
Thanks,
Tam
Network requests in Flash use the browser networking stack so cookies in Flex work just like any other browser application. Usually authentication in Flex is no different than it is with a standard web application. Send credentials to the server which it correlates with a session id. Every subsequent request (RemoteObject, HTTPService, etc) also sends that session id.
We have seen that the flash plug-in propagates the session cookie when we do blazeDS (http) remote calls
In the past we have worked with BlaseDS and HTTPServices. In both the cases the request is sent to the server over HTTP. Our server stack as Java (JBoss to be specific).
We noticed that the flex client used to send the session information with the requests to the server. We used same information to store and fetch Principal on the server.
In one case, we propagated the token to the client. This was to avoid multiple submits for same requests - hence we used the common HTML submission approach of token generation where with every response carries with itself a new token and the client has to sent it back to the server for executing the next request.
For the session expiration, there is a good chance that a user is working on the client for any local needs and not working with the server which may have caused a expiration on the server without impacting the server. In this case, we disabled the session expiration on the server and wrote custom code to handle events - keyboard and mouse on the flex client. If the application was not used for a specified time, the flex client would expire both the sessions i.e. local and server
What do you suggest the best way to do this with Flex?
$loggedIn=Authenticate::isAuthenticated();
if(!$loggedIn)return false;
$user=Authenticate::getAuthUser();
First Authenticate the user and if he is logged in create the session. Include this in your every PHP or Ruby file, and check it. Send the Session ID to Flex to maintain the state and you set the time for your session to expire.
The above code does check, whether the user is authenticate to access the PHP or ruby class files.

Resources