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!
Related
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')
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
I'm having a hard time understanding how to connect to the MongoDB Atlas Cluster from my react-native app. What I'm trying to do is basically take my data from my component login page (userName and password) and connect to the Atlas Cluster db to see if the data is there.
Im using React Native and use Expo to create the app. My login page opens up and I put in the data.
I want to take that data and then use the following code (from the Atlas Site Connection String) to connect and check.
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<userName>:<password>#testcluster1-dbdq3.mongodb.net/test?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
const collection = client.db("test").collection("devices");
// perform actions on the collection object
client.close();
});
Since react-native establishes a server, do I need to involve Express? Im new to this so I'm still trying to figure out what packages to utilize. Should I also install mongoose or mongoDB or both (from NPM). Im trying to wrap my head around how this works from a basic perspective and the packages required.
I want to perform a check against my userID and PW from my login page to the DB to see if the user exists. If the user doesnt, then I'll have them fill out some info and register which means writing a new user to my db.
So basically, I need to understand the code logic for:
Connecting to the db through my app and when to perform this
connection (when app loads or each time the login button is clicked)
Take data from my userName and password and search the atlas db to
see if the user exists. If so, then the next page loads.
If username and password doesn't exist, then I write the new user
and password to the db.
Thanks
I think you should rewrite the code following the format suggested by mongodb here:
https://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html
So essentially:
const MongoClient = require('mongodb').MongoClient;
//make sure to check connection string is correct here, since this depends on the whether you are running standalone, replica, sharded cluster
const uri = "mongodb+srv://<userName>:<password>#testcluster1-dbdq3.mongodb.net/test?retryWrites=true&w=majority";
MongoClient.connect(uri, { useNewUrlParser: true }, function(err, client) {
if (err) {
//error
} else {
var collection = client.db('test').collection('devices');
//client.close() should be called after you are done performing actions such as collection.update, etc.
}
});
you can use any npm package with Expo if it works with RN (React Native), but you may need to detach in order to do so. Any npm packages which include native iOS or Android code will not work with Expo out of the box, unfortunately. Because MongoDB NPM package just mentioned the Node.js in thier docs, this doesn't mean that it will work on React Native. That's why MongoDB made this page about JUST React Native https://docs.mongodb.com/realm/tutorial/react-native/
You may need to use Realm Package to connect to MongoDB with React Native.
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.
I have a node server running on localhost:5000 and I'm able to get a hash sent in the url with the following code:
app.get('/:hash', function(req, res) {
const id = req.params.hash;
});
I then also have a front end react app running on http://localhost:3000, and a proxy setup in package.json, but when I vistor http://localhost:3000/somehash I'm not able to retrieve the value some hash. Is there a step I'm missing to be able to get that value from react and pass it to node?
Thanks!
Background:
I'm creating a url shortener. User visits the react app and inputs a url to be shortened. Node returns a hash the user can use and share with others. Users who are given the hash url can visit and be redirected to the original url. Works fine on localhost:5000(node) but doesn't work on localhost:3000 (react). For some reason node isn't picking up the hash from react when the user first visits the page.
You must configure a route to receive the hash on react too.
Then, the react code can fetch the backend and get the URL from the hash.
And only then, the react can perform the redirection with window.location = URL
If you are using react-router-dom you can create the route like this:
<Route path="/app/:hash" exact component={YourComponent} />
Then, in YourComponent you can get the hash like this:
const {hash} = this.props.match.params;
Your backend is listening on port 5000 not 3000.
When you navigate to localhost:3000/somehash, you're asking your frontend to load the page somehash which needs to correspond to a route in React.
If you want to access the server's API on port 5000 through your React app on port 3000, you need to write the corresponding feature. For example an HTTP request to your localhost. It may look like this
// SomewhereInYourReactApp.js
const someHash = 'hello_world';
fetch(`localhost:3000/${someHash}`)
.then(response => response.json())
.then(myJson => {
console.log(JSON.stringify(myJson));
});