How to delete user from Auth0 on Next.js? - node.js

I can login and logout users on Next.js after reading these resources amongst others:
The Ultimate Guide to Next.js Authentication with Auth0
#auth0/nextjs-auth0 library
API Call Example
SPA + API: Node.js Implementation for the API
But nowhere could I find out if I can delete users using the auth0/nextjs-auth0 library.
I also looked into the module's handlers here.
Am I right to think there is no way to delete a user using the #auth0/nextjs-auth0 library?
If yes, what is the most preferred way to delete a user? I'd like to allow users to click a button in the browser to delete themselves from Auth0.
At this point, I'm thinking of using node-auth0 library to do it following this solution:
management.users.delete({ id: USER_ID }, function (err) {
if (err) {
// Handle error.
}
// User deleted.
});
But it requires a node back end, which I sort of wanted to avoid. Even so, is this the best solution or are there better ones? The Auth0 ecosystem is quite sprawling.
Edit 27 Oct 2020: Will try using node-auth0 library in "serverless" function in Next.js to allow user to delete their account over the weekend. Secrets are hidden with Next's runtime configuration. If this is not the best way to do it, please let me know. Thanks.

I believe you mean logging out a user by "deleting a user". Because If you want to delete a user from the database, you have to have node server which handles the db connection. If you want to log out the user, in "pages/api/v1" create a logout.js. in next.js, serverless functions or api functions are written in "pages/api".
import auth0 from "/utils/auth0";
// auth0 file is where you set the configuration for the auth0.
export default async function logout(req,res) {
try {
await auth0.handleLogout(req, res);
} catch (error) {
console.error(error);
res.status(error.status || 400).end(error.message);
}
}

Related

Existing React/Node project - adding AWS authentication

Premise: I'm a newbie, so I'm aware that some of my questions or issues might sound obvious to the more experienced.
My situation is: I have an existing React frontend and Node backend. I need to add authentication to my app, so that I can provide login (and future registration) for my colleagues. We use AWS resources and there is an existing user pool in Cognito.
How do I go about doing this?
I've done some research and everything points me to AWS Amplify, but I've found the existing resources very confusing. Amplify seems to create a new, separate backend when I run amplify init, but I need to stick with the existing one.
Basically, all I need is the authentication piece, I don't want to use anything else from Amplify itself.
Apologies in advance if I might have missed something obvious. Thanks.
I have solved this exact situation with the Amplify library.
You can utilize the Authenticator component from #aws-amplify/ui-react where the docs are here.
In the most simple form, it would look like this:
import { Authenticator } from "#aws-amplify/ui-react";
import Amplify from "aws-amplify";
Amplify.configure(awsExports);
const App = () => {
return (
<Authenticator>
{/* Pass app entry as children */}
{({ signOut, user }) => <Home signOut={signOut} user={user} />}
</Authenticator>
);
};
//Object holding AWS auth config
//This is a seperate file which is imported
export const awsExports = {
Auth: {
mandatorySignIn: true,
region: "YOUR REGION",
userPoolId: "COGNITO_POOL_ID",
userPoolWebClientId: "COGNITO_CLIENT_ID",
},
};
So in my app, I only use this Authenticator component which does all of the interactions with the cognito pool and nothing else from Amplify. There's a number of different props you can pass into the Authenticator component so certainly review the docs.

how to give user specific file access in express js

I'm using express js and passport js as authentication system also using view engine. I'm looking for a solution that would give access to user and let users see their file, not the other one's file. for example, in the image folder, the user would access to their files and after that, I want to pass these files to view engine. If I use the public folder, anyone is able to see every file in there. what solution do you recommend?
You should create a directory for each users.
then, for example, your URL is /show/files
the inside your logic, filter the directory by user info.
app.get('/show/files', (req,res)=>{
// filter resources by user info
})
don't forget to create a secure URL for your resources.
Bad Idea: /images/amin/profile.png
Good Idea:
create a route to serve your resources.
app.get('/resources', (req,res)=>{
// add query parameter for resource for example profile.png
// then check user directory and send it
})
your url converts into
/resousrce?file=profile.png
I assume you already have a login system in place, so all you have to do, is create a middleware that checks if the user is logged in, and checks if the image is his image.
app.use("/user/:user/**",function(req,res){
if (req.params.user == thisuser){
//serve the file
} else {
res.status(403); //access denied
res.end();
}
//check based on cookies whether the user has the permission to view this image
});
I would suggest you to use Passport.Js local authentication. You can look into the official docs - http://www.passportjs.org/docs/authenticate/ I personally have used this in the same scenario you're in.
Here is a litte code snippet of the custom middleware function I wrote using passport -
module.exports = {
ensureAuthenticated : function(req, res, next){
if(req.isAuthenticated()){
return next();
}
req.flash('error_msg', 'Please login to view this resource.')
res.redirect('/users/login');
}
}
Feel free to check the entire solution on my github repo -
https://github.com/StechAnurag/loginsys

Angular 2 (4/5) check if user authenticated, best practices

I am new to Angular and implementing authentication for users.
Most of suggestions on the web propose to save session/username in local storage and when user is back to the app, check local storage in order to display proper navigation (in my navbar I have different nav buttons for private and public views).
However, I found this solution having some drawbacks. For example, if session on server expired, or local storage was manually added, then when app will be initialising, it will show wrong buttons in navbar.
After that I came to solution - to use service before showing navbar buttons, to send request to server to verify if user from local storage with his session is currently active. And only after that I will display nav buttons.
Here comes a question: is it the most efficient way to proof check if user from local storage is logged in and session is active?
There is another way, which I was thinking, but didn't find solution.
Since my angular webapp and nodejs server are located in two different places, is it possible for the webapp to check authentication status (make a request from webapp server to my nodejs server) when index.html is requested and respond with pre-rendered navbar and user status (logged in or not)?
Thanks.
P.S. I am using PassportJS and Express on server side.
The best practise is to use AuthGuard and implement CanActivate to check whether user can view a particular part of the application. Also an authentication service is used normally to let the user login to system and gain an access token.
This access token is then used as Authorisation-Header on each request to server (this is where they will be in sync).
You will need to check for JWT/or any other type token on load which contains user information plus session time out.
If the token is invalid you simply redirect the user to login, otherwise it will allow user to go where they wanted to.
A practical example can be found here.
To have navbar showing different elements for authenticated and non-authenticated users, one of possible solutions will be
To use some "/auth-check" request in authentication.service.ts, which will have trigger every time an event of the result of checking authorisation of current user
...
interface ShareObj { [id: string]: any; }
...
currentUserId: ShareObj = {};
currentUserUsername: ShareObj = {};
public authenticatedBehavior = new ReplaySubject(1);
authCheck(): any {
return this.http.get('/api/auth-check')
.map((resp: any) => {
if (resp.authanticated) {
this.currentUserId['global'] = resp.user.id;
this.currentUserUsername['global'] = resp.user.username;
this.authenticatedBehavior.next(true);
} else {
this.authenticatedBehavior.next(false);
this.currentUserId['global'] = null;
this.currentUserUsername['global'] = null;
}
return resp;
})
.catch(e => {
this.authenticatedBehavior.next(false);
this.currentUserId['global'] = null;
this.currentUserUsername['global'] = null;
});
}
So, in navbar.component.ts there should be a listener for this event:
ngOnInit() {
this.authService.authenticatedBehavior
.subscribe(
data => {
// do change of UI of navbar depending if user logged in or not
}
);
}
To have error-iterceptor.ts file, where you should "catch" all failed requests and check them for Unauthorised response (401). If you catch such response, do authCheck() in authentication.service.ts to make sure that session of current user expired and notify all components which listen for authenticatedBehavior

Express JS routing based authentication

I have created node js app using express framework.
I have created middleware for restricting access to some routes.
Middleware actually works fine. but i have difficulties in displaying data.
Suppose In My app i have created route for display list of countries('/country/master')i.e html page which is using internally different/default route ('/country/') to get data from mongoDB.
In this case user will not able to see data cause i have not given permission to "/" routes. but i want to display data but not allow him to make use of "/" route to check data.
How can i deal with this case ????
The answer depends on your authentication strategy i.e. are you using session identifiers, access tokens, etc.
In either case I suggest that you break out the credential exchange (aka login) from the authentication. They should be separate middleware functions. Below is an example of what this looks like.
While this answers your question, specific to ExpressJS, it does leave out a lot of other details that matter when you are building an authentication system (like how to securely store passwords). I work at Stormpath, we provide user management as an API so that you don't have to worry about all the security details! It's very easy to integrate our API into your application, using the express-stormpath module. You'll have a fully featured user database in minutes, without having to setup mongo or a user table.
All that said, here's the example:
/* pseudo example of building your own authentication middleware */
function usernamePasswordExchange(req,res,next){
var username = req.body.username;
var password = req.body.password;
callToAuthService(username,password,function(err,user){
if(err){
next(err); // bad password, user doesn’t exist, etc
}else{
/*
this part depends on your application. do you use
sessions or access tokens? you need to send the user
something that they can use for authentication on
subsequent requests
*/
res.end(/* send something */);
}
});
}
function authenticate(req,res,next){
/*
read the cookie, access token, etc.
verify that it is legit and then find
the user that it’s associated with
*/
validateRequestAndGetUser(req,function(err,user){
if(err){
next(err); // session expired, tampered, revoked
}else{
req.user = user;
next();
}
});
}
app.post('/login',usernamePasswordExchange);
app.get('/protected-resource',authenticate,function(req,res,next){
/*
If we are here we know the user is authenticated and we
can know who the user is by referencing req.user
*/
});
You can positioning of middleware in you app.for example:-
app.get('/country/master',function(req,res){
})
app.use(function(req,res){
your middle ware for providing authentication
})
// other routes where authentication should be enabled
app.get('other urls')

Use everyauth's authenticate method inside a route that is exposed via API?

Using express.js and everyauth with mongoose-auth, how can I create an external authentication route for an API I'm creating? I want to do this to authenticate a native iOS app against the user records in my MongoDB.
So for example, here's some semi-faux code:
app.post('/api/auth', function(req, res){
if(everyauth.authenticate(req.username, req.password)){
res.json({success:true});
}
});
So my question is, How do I utilize everyauth/mongoose-auth's authentication from outside of everyauth's typical methods and views?
Answering my own question after doing some more digging.
The following seems to work for my needs. It returns the user record if the authentication is successful. I'm just responding with a basic success true/false message for testing purposes. This assumes that User is the model that you used for mongoose-auth.
User.authenticate(req.body.email, req.body.password, function(err, userdoc){
if (userdoc){
res.json({success:true});
}
else {
res.json({success:false});
}
});

Resources