Check login and render web application in web view - react-native

I'll keep this as simple as possible, the company I have recently joined has an established web application, they would like to build a mobile app to accomodate said web application.
Ideally they would like to create a very simple mobile app, so a standard login screen (username / password) and once authenticated they'd like to render the web application inside the app via a web view. Reason for this, they don't want to invest to much time on this and they'd also like to start sending notifications.
Problem:
The web application does not make use of web api's, it's your standard MVC application with cookie based authentication.
When the end user provides a username and password I need to somehow check in the background if the credentials provided are valid - I can't use an API
If the credentials are valid and the user becomes authenticated I'm to then redirect them from the login screen to the dashboard where they'll continue to use the web application view a web view.
Question.
How can I check in the background without using an API the credentials provided are valid?
How can I check the response for any errors and pass them back to the login screen for the user to see / action?
If the credentials are good and the user becomes authenticated how can I redirect the user accordingly?
Can anyone else think of a better approach?

Listen changes with onNavigationStateChange and based on url detect if a user is authenticated.
<WebView
source={{ uri: '...' }}
onNavigationStateChange={(navState) => {
const { url } = newNavState
// TODO
}}
/>

Related

KEYCLOAK : redirectUrl: '<YOUR_REDIRECT_SCHEME>:/callback'

For the part related to the keycloak configuration, what should you put in place of "YOUR_REDIRECT_SCHEME"?
redirectUrl: '<YOUR_REDIRECT_SCHEME>: / callback'
Plus, I get the following error message when I click on the "authorize" button {undifned redirectUrl}
First of all, it would be better if you had provided at least some context about your app, scenario, the setup, etc. so that someone who wants to answer could have some ideas about the problem space. See more at How do I ask a good question?
But just to respond to your question, I should say that when your app asks an OAuth compatible identity provider (in your case it's Keycloak) for an authorization_code, Keycloak will handle the authentication of the user and after a successful authentication, it will generate the code and should somehow return it to your app (in this case seems your app is a react-native). For mobile apps, you can register a custom URL scheme handler so that whenever a URL with that scheme is going to be opened on the mobile device, the OS asks your app to open that URL and process it. That could be anything like "myapp://".
Then in the redirect URL option in Keycloak, you should define a URL that begins with this custom scheme. The actual URL doesn't matter as long as it's a valid URL format. So when Keycloak tries to redirect the client to that URL, mobile OS will call your handler to process that request and you can get access to parameters that Keycloak has appended to the URL.
I suggest you to read the OAuth 2 spec for native apps for further details.

How to retrieve Stripe's Connect authorization code in react-native

I'm trying to setup oAuth for Stripe's Connect (Standard). In their setup documentation they say:
Step 1: Create the OAuth link To get started with your integration,
Your client_id, a unique identifier for your platform, generated by Stripe
Your redirect_uri, a page on your website to which the user is
redirected after connecting their account (or failing to, should that
be the case), set by you
Step 3: User is redirected back to your site After the user connects
their existing or newly created account to your platform, they are
redirected back to your site, to the URL established as your
platform’s redirect_uri. For successful connections, we’ll pass along
in the URL: The scope granted The state value, if provided An
authorization code. The authorization code is short-lived, and can be
used only once, in the POST request described in the next step.
The way I've implemented this is by sending the user to a React-Native WebView, and because this is a mobile application, a redirect_uri is not an option.
The problem is, I cant simply make a POST request to a url. there are user actions that must be taken inside of stripe, and ultimately stripe sends an authorization code to a redirect url.
So How can I obtain the authorization code that stripe doles out inside the WebView authorization process so I can finish the Stripe Connect user creation process?
You can use onLoadStart for WebView. Just check if the url from the synthetic event is what you specified in your stripe settings and handle accordingly.
onLoadStart={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
if(nativeEvent.url.startsWith("YOUR_REDIRECT_URL"){
// your logic here
}
}}
Follow the steps
step 1 : login in mediator strip account, now open new tab and paste below url in new window and replace client id "ca_****" with the account which you want to connect with mediator account ( client id ), and hit the url
https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_************************&scope=read_write
step 2 : now press connect button and find the code from new url like
https://connect.stripe.com/connect/default/oauth/test?scope=read_write&code=**ac_**************************

How to access express server session in nextjs api routes?

I am building my site with NextJs. I have a social login component where users can login via e.g. facebook Login. From the social login component (e.g. Facebook login) I get back user data (name, email) into my custom _app . So far so good.
With this user data, I want to create (or identify) an user on my headless wordpress backend. I want to use the Wordpress REST API for that. So I created an wordpress API restpoint which recieves user data, creates the user in wordpress if he is not existing yet, and then returns a JWT access token for calling other wordpress API restpoints where the user then can create some user specific data in my wordpress DB via my website.
What is the best approach to do this with Nextjs and a custom express server? My first idea was to use the new API Route feature and created a pages/api/test.js page like the example in the doc shows.
export default function handle(req, res) {
res.send({some:'json'})
}
So the whole flow starts in _app when getting the user data from the social login component. My first approach:
handleFBSocialLogin = (user) => {
//pesudo code:
//fetch("/api/test") with user data
}
When doing this my api/test.js is called and inside that i could then call my Wordpress API to get the token back, right?
But then i want to store the token server-side in my custom express server session, but how do i do that now?
And how do i read it from there in later requests to other wordpress API restpoints?
And - does that approach makes sense at all ?
Appreciate any input!

How do I get react-native-inappbrowser-reborn to trigger success upon successful Facebook login

I'm trying to setup a manual flow for Facebook login, as per the docs at: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
I've got my test Facebook app working as expected, i.e., I can login using a private web browser window fine. The URL I'm using is:
https://facebook.com/v3.3/dialog/oauth?client_id=<app_id>&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html
Now within my React-Native app, I'm using react-native-inappbrowser-reborn to present a SFAuthenticationSession on iOS. As per their docs (at https://www.npmjs.com/package/react-native-inappbrowser-reborn), I'm doing the following:
const redirectUri = "https://www.facebook.com/connect/login_success.html"
const url = "https://facebook.com/v3.3/dialog/oauth?client_id="+appId+"&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html"
InAppBrowser.isAvailable()
.then(() => {
InAppBrowser.openAuth(url, redirectUri, {
// iOS Properties
dismissButtonStyle: 'cancel',
// Android Properties
showTitle: false,
enableUrlBarHiding: true,
enableDefaultShare: true,
})
.then((response) => {
// Only gets to this point if user explicitly cancels.
// So this does not trigger upon successful login.
})
// catch handlers follow
Using the above, my app correctly open up an in-app browser and I can login fine using a test user for my test app. Upon successful login though, I don't get redirected back to the .then completion handler. It just stays in the in-app browser view and I see the same message from Facebook that I see when logging in using a web browser. It says something like "Success. Please treat the url the same as you would a password", or something like that.
I may be missing something here, but I thought the purpose of passing redirectUri as an argument to openAuth was so that upon redirection to that URI, the completion handler would be triggered.
Question: How do I redirect back to the completion handler upon login success?
I think that you already have a solution but thought it might be useful for someone else facing this issue. If you don't have a solution so far follow my instructions:
You can't directly redirect back to your application using deep link, since Facebook will not call a link `like myapplicationname://mycustompath´. It's only possible to call links using the https-protocol (https://...).
The solution I'd suggest you to use is to redirect using your own API (Facebook -> Your API -> Deep Link Redirection). You will understand why this is required in the most of the real world applications at the end of the instructions.
Starting from your react-native app call the authorize endpoint of Facebook with a redirection to your application and set the global deeplink of your app as redirect uri.
InAppBrowser.close();
InAppBrowser.openAuth("https://graph.facebook.com/oauth/authorize?client_id=YOURCLIENTID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook", "{YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}")
.then((response) => {
handleAuthorized(response, LOGINTYPE.FACEBOOK);
});
Now after login you'll be redirected to your API with the authorization code token as query parameter (e.g. https://YOURDOMAIN:PORT/auth/facebook?code=AVERYLONGCODESENTBYFACEBOOK)
Using this code token from the query parameter, you make another API Call to get the access_token for the user
{GET}: https://graph.facebook.com/v15.0/oauth/access_token?client_id=YOUR_CLIENT_ID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook&client_secret=YOUR_CLIENT_SECRET&code=AVERYLONGCODESENTBYFACEBOOK
Facebook's API will send you an answer as JSON with the access_token inside.
You can make another call using the access token of the user, to get the userId and the username
{GET}: https://graph.facebook.com/me?access_token=ACCESS_TOKEN_SENT_BY_FACEBOOK_IN_PREVIOUS_GET_REQUEST.
If you need the e-mail address for the user you have to make another call. Make sure you'd set the permission to read the e-mail address for your app on the developer portal of facebook.
The following request will return you the id, name and the email of the user
{GET}: https://graph.facebook.com/USERIDFROMPREVIOUSREQUEST?fields=id,name,email&access_token=ACCESSTOKEN
I think you want to save all these information to a database and create a session in order to keep the user logged in and therefore all the requests described will be useful for you in a real application.
After doing all the backend stuff, you're ready for the redirection using deep link. To do that, set a meta-tag to redirect the inappbrowser to your application:
<meta http-equiv="refresh" content="0; URL={YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}" />

AngularJS: how to implement server-side or client-side authentication?

I want to authenticate an AngularJS app, it is running on top of Node.js and Express.js backend with Jade templates.
I thought of the following strategies:
1) server side authentication - store credentials in session variables and redirect the user to the AngularJS app, the problem: how to pass the credentials to AngularJS? (I can render those as Jade variables, but how can I read them with AngularJS?), also, how to handle session expiry ?
2) client side authentication - do the authentication with AJAX calls and get the credentials,
the problems: how to handle 'session' expiry and how to remember users so they won't have to login every time the app starts ?
any insights may help.
Setting up authentication for a Angular.js application isn't any different then setting it up for any other website. You post your username and password to the server and it will set a session/cookie if your credentials are correct. To get data (in your case crdentials) from the server you use the same techniques you always use with Javascript. Xhr, websockets, render values in a text field, ...