Preventing Direct URL to views in angular + firebase web app - angularjs

I'm not an expert as I started working in firebase and angularjs a few weeks ago. I'm building a server based web application using firebase, nodejs(for server) and angularjs and I've a login scenario for my web application, Now I want to prevent direct URL access, after checking that a user is login or not. I want to redirect it to login page if user try to access via direct URL.
I tried using this but it doesn't seems to work.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
Can some provide me a working example of preventing access to URLs using angularjs and firebase?
Thanks in Advances

Related

Redirection error Laravel Passport PKCE - local

I have a React site trying to get access token from my Laravel oAuth portal (using Passport). As I understand from the documentation, I create the state,code challenge and code verifier on my react app. I create a url with the required parameters and make a redirection to /oauth/authorize. The complete code for the redirection is window.location.replace('http://portal.test/oauth/authorize?' + paramsStr). http://portal.test is my oAuth portal (using Valet) and paramsStr contains all my parameters: client_id, redirect_uri, response_type, scope, state, code_verifier, code_challenge, code_challenge_method.
I am redirected to the portal as I should which redirects me to the login form. Once logged in, I have to approve the authorization request. After that step, I am supposed to be redirected to my React app to verify the state parameter and then make a POST request to my oAuth portal to request an access token. (again, from the documentation)
The url in my browser is still http://portal.test/login (the oAuth portal url) where it should be http://auth.localhost:3006 (the React app). I do have kind of a popup that opens, showing the content of the React app but I have a problem with my cookies. In the first step, after creating the state,code challenge and code verifier, I store those (using react-cookie). If I check the cookies right after, I can see them. If I go to another page of my React app, I can see them. If I manually go to another url (like google for example) and then go back to my React app, I can see them. So I know that setting the cookies does work. But in that weird popup I can't access the cookies.
I guess that a redirection issue and I can't access them because the url in the browser in not the url of my React app. How can I fix that ?
Relevant code for the login
const [cookies,setCookie,removeCookie] = useCookies([]);
setCookie('code_challenge',code_challenge);
setCookie('code_verifier',code_verifier);
setCookie('state',state);
console.log(cookies); // this shows the 3 values
window.location.replace('http://portal.test/oauth/authorize?' + paramsStr;
Page I am redirected to within React app
const [cookies,setCookie,removeCookie] = useCookies(["foo"]);
console.log(cookies); // empty
In the url to /oauth/authorize the parameter redirect_uri is http://auth.localhost:3006. In the DB in the oauth_clients table, the redirect value is the same.

Single page applications and rendering private pages

I have two different account types in my application [user, admin], the two log in from the same page on the website: http://example.com/login, the log-in page sends the entered email and password to the server, the server then replies back with 200 OK HTTP code.
Now, the front-end of the Admin contains pages that a regular user should not see (think of the CMS pages), these pages must only be rendered to the admin, and shouldn't be bundled in the code and served to the regular users, even if their browsers will not render them.
because the front end of the Admin holds API endpoints that shouldn't go public (even though hitting them requires authentication).
Is it possible to make the server decide which pages (components) it should serve back to the client based on the user role in a single-page React application?
Is that available in Next JS or something like that?
I found that my question was similar to this one Is it insecure to include your login page in your single page application?, but I thought that this question deserves its own thread, because it's critically important and doesn't seem to be answered well on the internet anyway
For a Nextjs auth implementation with cookies and _middleware would look something like this:
export function middleware(req) {
const activeSession = req.headers.get('cookie');
const url = req.nextUrl.clone();
if (activeSession) {
if (req.nextUrl.pathname === '/login') {
url.pathname = '/';
return NextResponse.redirect(url);
}
return NextResponse.next();
}
url.pathname = '/login';
return NextResponse.rewrite(url);
}
You can set any cookie using any of the following methods:
https://github.com/vercel/next.js/tree/canary/examples/with-cookie-auth

Custom React GUI for oidc-client-js

is there a way to user your custom React GUI with oidc-client-js? I know that if you trigger authentication endpoint using:
// PopUps might be blocked by the user, fallback to redirect
try {
await this.userManager.signinRedirect(this.createArguments(state)); //Shows midleware login form
return this.redirect();
} catch (redirectError) {
console.log("Redirect authentication error: ", redirectError);
return this.error(redirectError);
}
Middleware will try to render its predefined login form:
However I have my own React form and I only need to pass to OICDClient params (email,password) and get back User instance to display UserName etc. Something like:
var loggedUser = await this.userManager.signinCustom(state.loginEmail, state.LoginPassword); //Login using credentials
I don't want to write all the logic by myself I really want to use all functionality from OIDCClient - only with my GUI (loginForm, registerForm, updateUserForm etc).
I'm using scaffolded library from MSDN using command:
dotnet new react -o <output_directory_name> -au Individual
Is there any method/implementation to initialise oidc-client-js from React components and not user default GUI forms?
Thanks a lot!
I might be missing some thing but the whole idea of using a 3rd partly federated auth provider be it your own/your company's SSO (say developed using Identity Server 4) or say Google sign in(say using their Firebase JS kit) or Microsoft sign in, Facebook sign in etc. is that you will be redirected to their authentication endpoint where you then use say your google credentials (if you are using google sign in for example) to sign on to google auth servers. Once you do that then a payload (consisting of an identity token and access token) is returned back to your redirect URL which you must configure for your specific app.
By saying you'd like to provide your own sign-in form you are missing the entire point of using a 3rd party authentication provider. Besides, you/your app shouldn't know about user names and passwords and you don't want to have access to all that information. All that you should be interested in knowing whether the user, who are using one of the federated authentication providers, that you would have configured for your app, are who they claim to be and you then delegate all that heavy lifting to your 3rd party authentication provider.
Besides, say your company has a SSO system of their own then all your company's app will use that SSO system and from a UI perspective you want to show the same login screen so as to give a consistent user experience.
In addition, if you show me a google authentication button and then on clicking that button you show me some weird form that doesn't look like the typical google picklist sign-in form then I'll shut down your app before you can say hello, and, I suspect most user would (and should) do the same. The reason being that when you show me a google sign-in page then I know that you/your app will only get back what you need and I wouldn't ever entrust my google user name and password to any other application.
If you really want to have your own authentication form then you'll have to manage user names and passwords yourself, the way we used to do things probably over 10+ years back.
If you decide to go the route of setting up your own authentication system and then say use identity server 4 then yes you can certainly change the UI and customize it to your heart's content, but that will happen at the server level, not at the level of your react app. Point being that in any SSO system the user will be redirected to the that auth provider's endpoint where they then authenticate (and, optionally, provider permission for your app to use certain claims) and once they do that they they are redirected back to your redirect endpoint with a payload (JWT token).
Lastly, even if you could some how wire up a client side sign in form, I'm not sure you would want to use it. Passing passwords & user names over the wire isn't a good idea. You'll always want to use a server rendered sign in form.

Teams Tab for dynamic SharePoint page / authentication problem

Heyo,
I am trying to build a multi tenant Teams App with personal tabs. The goal is: the user is authenticated (silently like explained in the Microsoft example, a static html page with the JavaScript code is hosted in an Azure Storage), then my custom web service is called and answers with a SharePoint-Online URL which contains an SPFX Webpart. Then the user is redirected to that page. When the user is not registered he gets an error page instead. The problem here is, that I am not able to redirect the user to that SharePoint page. The SharePoint page won't open in the iframe of the Teams tab because the tab's domain is the domain where my static web page is hosted. So my first question is how can I achieve this? (I do not know the SharePoint URL at build time, i do not know if the user has a page at all. This is determined in the custom web service at runtime)
A different approach would be to build a custom JavaScript application (in react, like my SPFX webpart), host it on my static web page and communicate with the SharePoint from there. To test my idea I added permissions for SharePoint in my Azure AD application, wrote a simple call to the SharePoint with the obtained token.
var req = new XMLHttpRequest();
req.open("GET", "https://[tenant].sharepoint.com/sites/[sitecollection]/_api/web/lists", false);
req.setRequestHeader("Authorization", "Bearer " + idToken);
req.setRequestHeader("Accept", "application/json;odata=verbose");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
var result = JSON.parse(req.responseText);
}
};
req.send();
The problem is my SharePoint is answering with 401 and "Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown" error in the response.
Is this some sort of CORS problem or do I need a different type of token for SharePoint? Or do I have to use a complete different JavaScript library to authenticate vs SharePoint.

Django Rest Framework / AngularJS - Users do not get redirected anywhere after logging in, even though I have set LOGIN_REDIRECT_URL in settings.py

According to this link: http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/#adding-login-to-the-browsable-api
I need to add the following code to my URLs.py:
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
When I added this, users can log in by going to the "api-auth" URL and using the default DjangoRestFramework login interface. After a successful login, users are directed to "/test" because I have the following code in my settings.py:
LOGIN_REDIRECT_URL = '/test'
I wanted a way for users to be able to log-in using my own custom interface but by using DjangoRestFramework's built-in code for logging users in, so I created my own template. The login form in the template sends a post request to
api-auth/login/
and sends the user object (which consists of a username and password in JS) along with the POST request. No errors are returned, so I'm assuming the login is successful. However, it does not redirect to any URL (I was expecting it to redirect to "/test").
Any idea why it does not redirect anywhere, and how I can make it redirect to "/test"?
Edit: I am also using AngularJS on the frontend.
LOGIN_REDIRECT_URL is basically from django.contrib.auth so I wouldn't except other auth backends to use it, at least not necessarily/automatically
Also if you're logging through REST say from an AngularJS, even if after the REST API login is successful and returns a redirect response, there is no guarantee that the AngularJS app will navigate to that page because the login REST API was hit using an XHR request (from $http or $resource etc)
I'm using a slightly different REST auth lib than you, called django-rest-auth (not the BrowsableAPI that comes with DRF), I'm authenticating from AngularJS, and after the call is done with success, I simply navigate the app to a new URL
djangoAuth.login(username, password).then(function(){
// make angularJS navigate to new page when login is successful
// $location.path(...) or some other way
});
Bottom line is, since you have an auth API, you can make a small AngularJS page, with login form, then when login is successful redirect with AngularJS
Worth a look
I'm using these two libs that are meant to be used together, they offer REST auth over DRF, and optional a AngularJS lib to help with the frontend
https://github.com/Tivix/django-rest-auth
https://github.com/Tivix/angular-django-registration-auth

Resources