Node Rest API with static Key Authentication - api

I wanted to allow my APIs to be access through a single key only. This API key will be in my environment variable file. Every time user will try to access my API. I'll first check whether key
present in the request body or not. After that I will check key matching with my fixed key. If both the condition will get satisfied I'll call api otherwise will response with 401 error.
I tried looking for middleware but not found any solution for this situation. Passport can be used
but it is asking for username and password for basic/local/digest strategy, Oauth and OpenId are based on third party provider.
I solved this by adding key check functionality in my controller itself.Like router directly route to
my API and after getting into the API controller I am call key authentication function. But it seems not to be standard way.
Instead I wanted to stop user at route lever itself.
Please share appropriate solution if anyone come across such situation.

If you really just need to check the key it should be super easy to do in a route middleware, eg:
var checkApiKey = function(req, res, next) {
if (req.body.apiKey !== process.env.API_KEY) {
return res.status(401).json({status: 'error'});
}
next();
};
app.all('/api/*', checkApiKey);
app.get('/api/something', function(req, res) {
return res.json({status: 'ok', message: 'You knew the key! Congrats!'});
});

Related

how can i remove token from specific Api route in laravel

I use JWT token in my project and i have an Api route that i want to remove token that send from user.
I searched a lot and many people say to put my route in $except array in VerifyCsrfToken class , but it does not work.
I want this solution because if user send request with token, the result that returned is differ from result that returned without token.
///edited
I have one route without middleware and guard, in Product model i wrote a global scope that affect on is_active column.
public function apply(Builder $builder, Model $model)
{
if (Auth::guard('manager')->check()) {
return $builder;
}
if (Auth::guard('customer')->check()) {
return $builder->where('is_active', '=',true);
}
return $builder->where('is_active', '=',true);
}
if manager use this route for products, all products returned.
i want the user's role have no effect on output.
in other word i want to remove token from some api routes
I am not sure I fully understand your question.
But isn't it possible to just adequately add one layer of middleware and do your filtering there?
So you could check if the user has a token or not and react accordingly (like forwarding the user on a specific route).
In case that may help, you can find a few middleware related videos here explaining how it works.
VerifyCsrToken is for CSRF and it's different with JWT token.
In this situation you have 2 different solution:
When your user is sending JWT token, It means your user was authenticated, and you can get user's object and send proper response.
You could make 2 different controller, and two routes, one of them for without token and another one with token, And according to user request, make your proper response.

best practices for authentication in react native

I'm a beginner in react native and I'm creating an app. I've done some research about how to make a secured react native app, but I didn't found much information. I've come up with a "solution" myself, but I want to make sure this is the right way to do this. So I need the help of some react native/javascript/security experts if possible, to quickly check if my approach is OK or not?
I have included 3 questions in this text, but obviously they're related. I've put them in bold. Feel free to answer one or more questions, I appreciate every answer!
I'm creating an app in react native. For a user to be able to use the app, the user should create an account and sign in. I'm using an JSON web token as an access token to authorize the requests made from the app to the server, and to identify the user (I store the user ID in the JSON web token).
At my server, I first check if the access token is valid. If so, I get the user ID out of the access token and use this user ID to identify the user.
For extra security, I'm also using refresh tokens, because an access token is only valid for 10 minutes. When a user send a request with an expired access token, the server responds with a 401 not authorized status.
To make my code more "managable", I've created a wrapper function in react native. I wrap every "request function" (every function where I do a GET/POST/PUT/DELETE request to the server) with this wrapper function. This wrapper function checks the response of the request. If the response status is 200, the response is returned to the code. If the response status is 401, the refresh token is send to a specific endpoint to obtain a new access token. When the access token arrives at the app, the previous request is made again with the new access token. The wrapper function also stores the new access token in (temporary) redux (keychain or shared preferences). 1. Is a wrapper function a good idea? For me, it's more manageble because now I'm reusing the code.
Every time the user opens the app, a new access token is requested, and when a user closes the app, the current access token is deleted, even if it is not expired yet. That way, I want to make sure that every app "session" starts with a new access token. 2. Is this okay? Or should I prevent unnecessary requests to the server when I still have a (possibly) valid access token?
In my react native app, this wrapper function is located in a context component. This "authentication" context is wrapper around my other components in App.js like this:
<AuthenticationProvider>
<AppNavigator />
</AuthenticationProvider>
This way, my wrapper function is accessible to all my other components. My authentication context looks like this:
const AuthenticationContext = createContext({
accessToken: null,
wrapperFunction: () => {}
})
const AuthenticationProvider = (props) => {
let accessToken = null
const refreshToken = useSelector(state => state.auth.refreshToken)
const wrapperFunction = () => {
// wrapper function
// set the access token
// await fetch('server endpoint')...
}
return (
<AuthenticationContext.Provider value={{ accessToken, wrapperFunction }}>
{props.children}
</AuthenticationContext.Provider>
)
}
3. Is using a context a good practice to do stuff like this?
Server-side, I store every refresh token in a database. When a user requests a new access token, I check if the sent request token still exists in the database. If not, I have revoked access for this user and the user should be logged out. This way, I want to make sure I can "manage" users.
Yes, it makes sense. Actually I can't think of a better way to manage the scenario you mentioned. When you wanna temper the request before it's sent, you will need a single function to do so. You could also use some hooks e.g. onBeforeSend and onAfterReceive, but in your case I don't see any extra value for this.
I do not agree with the deletion of a valid token. You can still send request to server on every app start to get user's last data -might have changed on another device-. I don't understand the logic of starting the app with a new session -maybe more information?
I don't think you need to pass the wrapperFunction/token using context. It would be best if you could send user data by context. you wrapper function can access the token directly from asyncStorage. And each component can call the function directly by importing it.
I believe you are taking the approach of using a wrapper function since the relevant API requests are made directly in components. The best practice is to move such requests outside (E.g. Redux actions with a middleware like redux-thunk) the components.
It's better to check if the access token is expired (by decoding the token) before sending the API request and retrieve the new access token. This will reduce the amount of requests to server. You can implement a common request method which handle this check as well.
I think since your access token expires every 10 mins this is unnecessary. Is there a specific reason to start each session with a new access token?
You can pass in user access details using the context. I think it's matter of preference. Passing in the wrapper function is not needed if you're handing the requests through a common request method.

How I secure my Vue.js routing when I work with an API and JWTs token?

I’m building an app with Adonis.js for the API and Vue.js for the front-end. I’m using JWT token to secure all routes of my API.
I understand the power of JWT to secure routes of API. When user create an account, a token is created to identified the user.
When I call my API from Vue I write the token of the active user in the header, and in my API I verify if the token is « active » and if is attributed on a user account ( and after that a make call to my databases..).
But the problem is (for me) I don’t understand how I can make a middleware to my vue route (verify if a user is authentify). I’have read some tutorial about that, and the conclusion is => store the token in local storage (ok, it’s logical) and make a middleware just checking if token exist.
But in my opinions this option is very not secure, because I can « enter » in my routes if I create a token manually in the local storage..
I’m very confusing about this concept.. can you open my eyes ehe ?
Thanks
So yeah, you were right that you should be using Vuex to store the value for the token to retrieve it using getters in your components/middleware. Your state would look something like this:
export const state = () => ({
api_token: localStorage.getItem("api_token")
});
And getters would look something like this:
export const getters = {
apiToken(state) {
return state.api_token;
}
}
To protect routes in the front-end you would be using router guard functions (https://router.vuejs.org/guide/advanced/navigation-guards.html). To give you an idea, this is what a simple check would look like:
router.beforeEach((to, from, next) => {
if (!store.getters["auth/apiToken"]) next('/login');
else next();
})
Good luck!

Authentication with JWT using GraphQL

After some search on the web I found that the best way of JWT authentication when using GraphQL is by inserting the JWT token into the GraphQL context. By doing so, resolvers can have access to it and check if the user is logged in, has permissions, etc.
I was wondering if I will need to place the authentication logic/function into every resolver that authentication is required. Is there a way which I could set by default (eg. middlewares) the authentication to every query except for login/logout/register/forgotpasword ones?
This question pops up every so often but not enough has been discussed. I think the answer lies not in the technology but in which way best suits your needs.
It is important to be mindful when adopting GraphQL that;
You don't have to give up on REST
You can have more than one GraphQL endpoints
Here are some suggestions based on my experience with implementing GraphQL
Authentication
For login/logout/forgot password and the whole shebang, consider going old-school. Form Post + Server-side rendering, REST API served us well for decades. Many third-party authentication services are based on this (Facebook Login, Google, OAuth2... etc). I tend to avoid using GraphQL for this purpose.
Authorisation
The logic to check if the requester is authorised to access the GraphQL can be generalised to 2 levels
GraphQL services
Essentially you check to see if the requester is authorised to use GraphQL service. Typically it's easier to check if the requester is authenticated, else deny access to the service altogether. This is typically done via a web server middleware.
There will be times where you'll need to expose some GraphQL queries to anonymous users, and I tend to lean towards having another 'unrestricted' GraphQL endpoint. This endpoint tends to have little to no mutations, exposes a limited subset of information and restricted nested queries.
Basically, you look at the data and decide which information/operation is public and which is not. IMO this is much easier to manage and secure than have a single GraphQL endpoint and implementing authorisation checkpoints in every query path/resolver.
Fine grain authorisation
At this stage basically, all requesters are authenticated users. We may need to question:
Is the requester the same user whose info is currently viewed?
Is the requester a friend of the user whose info is currently viewed?
Is the requester a member of the company whose info is currently viewed?
This is where putting the checking logic in resolvers (or models) really makes sense. I personally think resolvers are a great place to do this. Coupled with DataLoader the implementation can still be fast and effective.
Hope this helps!
No need to do checking in resolvers. You can add a middleware in your server side.
const graphQLServer = express();
graphQLServer.use('/graphql', function(req, res, next) {
var token = req.headers.token;
if (token != null && token != 'undefined') {
//Do token verification here
next();
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
})
Just try this

JWT authentication with Vue.js

I'm working on an SPA with Vue.js and vue-router and I'm now dealing with authorization/authentication using JWT. I have the back end (API endpoint) sorted out, such that it will issue a token in response to a login and check for the requisite header on subsequent requests. I now want to implement the client (Vue.js) side.
As I understand it, fundamentally what I need to do is to require authentication for all routes apart from '/' and '/login'. If authentication is present then I submit the token (which is stored in localStorage after a successful login) in an Authorization header. If it fails to validate successfully on the server, then the user will be redirected to '/login' as a result of the error response.
So, I have a couple of questions about what I need to do to implement this:
How do I best submit a header with every request, apart from to the login endpoint? I know with JQuery, which I'm using for AJAX, I can configure a global 'ajaxSetup' which will cause the header to be submitted with each request, but how can I specify exceptions? It's cumbersome to individually add the header to each API endpoint request.
Similarly, how to I set up an authentication pre-check which applies to all routes apart from the 2 mentioned ('/' and '/login')?
Given that I'm using the presence or otherwise of apparently valid authentication (apparently because it still has to be validated on the API endpoint) to determine whether or not to show certain menu items, etc., is it feasible to make this more granular and show different things for different permission levels, as determined by the 'scope' field in the token payload? Clearly the simplest way of dealing with a JWT token is purely to determine whether it is present or not, so no parsing of content is required at the client end. But given that JWT does allow meaningful content, is it a bad idea to try to make use of that meaning on the client side as well as server? Obviously this becomes less practical if the token is itself encrypted, so my idea would be to use unencrypted tokens (and ensure nothing of any consequence is exposed in the payload).
You can do global headers, and when the user is authenticated, add to the global headers the token like this example , I'm using Axios.
axios.defaults.headers.common['Authorization'] = "Bearer"+ authtoken.token
For checking the authentication of the user or to manage parts of your website, simply add global variable, and when the user is authenticated set the variable to true. Alternatively, use Vuex and it will be easy and the element you want to hide or to show to the user simply add v-if to the element like (example using Vuex)
<div v-if="this.$store.state.authenticated"> Hide Element from Guests </div>
And for the route, in your routes add meta field to indicate the path is requires authentication
{
path: '/dashboard',
component: DashboardPage,
name: 'Dashboard',
meta: {requiresAuth: true} // Meta Field , you can name it
}
In your Vue Router configuration add navigating guards that check the presence of the meta field, and if true check the if the user is authenticated
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if(to.meta.requiresAuth) { // check the meta field
if(store.state.Authenticated) { // check if the user is authenticated
next() // the next method allow the user to continue to the router
}
else {
next('/') // Redirect the user to the main page
}
}
else {
next()
}
})