NextJS access cookie response in React components - javascript

I'm using Next js along with Express backend, for authentication I,m using Cookie, and for protected routes, I have used Next js middleware which is fine, but now I want to access the cookie response in React components to check if we have a cookie then I want to hide register and login links from the navbar, please anyone can help me?

You can use the js-cookie package to access cookies on the frontend.
Do an import in the react component first:
import Cookies from 'js-cookie'
Then access the cookie, maybe do it in useEffect to avoid any issues:
useEffect(()=>{
const allCookies = Cookies.get();
console.log(allCookies);
}, []);

For client-side checking, you can use cookieCutter
import cookieCutter from 'cookie-cutter'
cookieCutter.get('myCookieName')

Related

Calling Protected API Routes from Laravel Vue.js or React.js MPA

I am building a Laravel Vue MPA Project using Laravel Default Authentication where most of the pages are served by Laravel. But for Form submission I am using Vue Component and the form is directly submitted to the API route. Each Page of Mine contains several vue component. An example is given below
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-6 mx-auto">
<profile-component>
</profile-component>
</div>
</div>
</div>
#endsection
The Problem I am facing is to access protected API routes. For API Authentication I have used Laravel Passport. In the above example if I try to update profile I will have to send Passport Token As well. I read many articles saying not to store auth token in localStorage thats why I tried to use Laravel Secure Cookie. But the problem is I can not access the secure cookie from vuejs then how I can send my token In vuejs API call.
I have also tried to store it into database user table and tried to pass token through props but feeling like it is not safe to pass it as props.
Now I couldn't understand what to do. should I use localStorage or there is any other better way of doing this.
Thanks in advance if anyone can help.
I suggest you use a library like Axios to make your API requests from Vuejs. With it, you can include the withCredentials option in the request, which will automatically use your API token:
axios.get('some api url', {withCredentials: true});
You can also set the parameter globally when creating the Axios instance:
import axios from 'axios'
const instance = axios.create({
withCredentials: true
})

how to hide nextjs api routes from being directly accessible through url?

Is there any way to make next.js API routes response data hidden when accessing it through URL? I want to hide the routes because there is some data I don't want to be directly accessed by the user.
Probably quick & simple way to protect the API routes is through the stateless session management libraries like iron-session with save / creation and destroy endpoints to validate and invalidate the Next JS api routes
Try this github example by Vercel. This might a be good starting point.
Remember: Always use a best authentication mechanism to protect any direct api route call with appropriate privileges in place. DYOR
There is no way to hide API routes from users through url in nextjs. In fact, nextjs API routes are publically available to anyone when you host the website without exporting and hosting from out folder. I ended making server-side routes using node express and then connected to the frontend in nextjs.
It is extremely unworthy effort to hide API routes. and for protecting essential data in API..there is CORS and Authentication methods can prevent noicy unwanted traffic I found brilliant blog on this
https://dev.to/a7u/how-to-protect-nextjs-api-routes-from-other-browsers-3838
You can set an authorization header that checks auth key everytime user access that API, that way normal user wont be able to access the page without knowing the auth key
In Next.js version 13 you can use middleware to stuck the user from directly checking the route of your api by checking the req.referer then only your app can call and api of your app. Auth token can also be use inside middleware.
https://nextjs.org/blog/next-13-1#nextjs-advanced-middleware
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(req: NextRequest) {
const url = req.nextUrl
const { pathname } = url
if (pathname.startsWith(`/api/`)) {
if (!req.headers.get("referer")?.includes(process.env.APP_URL as string)) {
return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });
}
}
return NextResponse.next()
}
export const config = {
matcher: ['/((?!_next|fonts|examples|svg|[\\w-]+\\.\\w+).*)'],
}
process.env.APP_URL is the url of your app for example : http://localhost:3000

Share data between native app and mobile browser

I have a native application which installed on a client mobile device.
Other than that, I have a web application that this client can access via a mobile browser.
I would like to sync and pass information (such as identifiers or other user data) between the application and the web browser.
Is there any WebAPI that can help me do so?
I found the getInstalledRelatedApps that can indicate me whether my application installed or not, but what about sharing an information between those two? Is it possible somehow?
What frameworks are you using? Can I consider that you are using Node JS, React and React Native?
You could use express in the backend to create your own API, call it on the Frontend/Mobile with Axios, and then you could pass the parameters by setting them on the route. I.E. let's say that you want to pass on the tea ID from the mobile app to the web app so you can see them on your navigator:
// BACKEND
const express = require('express');
const routes = express.Router();
routes.get('/tea/:teaId', function (req, res) {
res.send(req.params);
});
module.exports = routes;
// MOBILE
import React from 'react';
import axios from 'axios';
import { Linking } from 'react-native';
const api = axios.create({
baseURL: 'http://your-url-here.com/',
});
let teaID = 22;
function sendToWeb() {
Linking.openURL(`https://your-url-here.com/tea/${teaID}`)
}
You can also pass Header Authorization in case that you want the user to be logged on and skip the login step or something related to it.
Express Routing
About Axios
I hope that this can help you a bit! And sorry if it seems confusing, it's my first time trying to answer a question!

SecureStore deletes my token each time I refresh the expo client

I have problem retrieving my authentication token from SecureStore while I develop my app in the expo client.
I’m trying to implement this authentication flow from react navigation using secureStore instead of Async storage: https://reactnavigation.org/docs/en/4.x/auth-flow.html
Currently, when I login my token is stored in SecureStore. I know this because I can then use it for authorising my requests.
My problem is when the expo client I'm developing my app in refreshes, the token seems to disappear so I have to sign in again.
Does the expo client app refreshing clear the token from secure store or is there a bug in my code that stops me from retrieving the token when I am opening my app again:
useEffect(() => {
_bootstrapAsync = async () => {
const token = await SecureStore.getItemAsync('token')
navigation.navigate(token ? 'App' : 'Auth');
};
_bootstrapAsync();
}, [])
I have a hunch what it could be.
Is the token stored correctly?
And won't the token be overwritten when reloading?
I don't know which module you use for saving but I recommend "expo-secure-store".
In my applications when I reload everything works.
Try wrapping a try-catch block around both getItemAsync and setItemAsync and see whether you're getting any errors as a start.
There's also a chance that you're using an old import syntax, make sure you're using import * as SecureStore from "expo-secure-store", this will cause an error like undefined is not an object so the data was never saved.
Solved this by adding a useEffect that would check if there is a Token, if there was a token i set it and if not i removed it.

Send headers with Vue-Router

I already searched for a good while on the Internet and even checked all suggested questions here, but I found nothing.
Basically, I'm using vue-router to load views when the user clicks on them (without prefetching, just lazy-loading), using a function that imports the Vue view/component. To better visualize, I made a barebone example of what I'm doing:
const router = new VueRouter({
routes: [
...
{
path: "/a_page",
component: function() {
return import("./views/A_Page.vue");
}
}
]
});
I'm using Express in the backend to protect certain routes, because protecting it in the Frontend is wasted effort, since the user could bypass the 'protection' easily, if he wants to. Also all views have their own splitted .js file (using "webpackChunkName") and Express needs a Bearer Authentication Token header for every API call OR .js file requested. This works great with Axios (responsible for fetching API data) where you can manually define a header, but vue-router hasn't this option, and since it doesn't send the Authorization header, it doesn't authenticate, Express blocks the file with a 403 and vue-router fails to import the file.
Is there any way to send the Authorization header with the import (which is basically just a GET request)?
Thanks in advance.
If someone thinks I'm approaching the problem in a wrong way, feel free to comment and suggest another way.
EDIT: The suggested duplicate question was given too little attention and the only solution given (which is basically split in 2) doesn't work with the current webpack anymore; onload(event) and onerror(event) get undefined.
You could use a router guard instead of protecting with basic auth.
I use this method, along with lazy loaded routes. If the auth fails you can redirect the user to a login page.
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
If (auth) { // get value of cookie etc for a jwt token or similar auth method
next() // proceed
}
else {
next(false) // cancel navigation
// or
next(“/login-url”) // redirect you login url
}
})
Additionally, you could use an axios method to auth on each route change.
If you want to send up the Authorization header (which doesn't seem to be an easy task, given that no one knows how to go about it...) I think you could override webpack's jsonp function that it uses to load the chunks in splitChunks...
Here's the docs for the webpack function that loads the chunks
You'll override your webpack config with your modified chunk loading function and then tie that into your vue.config.js like so...
// vue.config.js
module.exports = {
configureWebpack: require('./webpack.config.js')
}
All this being said, I would suggest protecting your frontend assets much earlier than when you need to be loading your split chunks and not requiring the Authorization header to serve your static assets.
Sometimes you can do this at the network layer (load balancer, etc) depending on your use-case. Other times using a server-based approach, like rendering your app w/ Nuxt, will be what you want.
If I'm understanding correctly (feel free to correct me), would you be able to do an auth call with axios prior to the actual routing, or perhaps upon the routing using a mounted call? Especially if there is no valid authentication you can then either redirect to a login page or re-route to an error page.
Feel free to let me know if I'm misunderstanding.

Categories