Hello i'm trying to code auth for my app i'm using json web token the problem is when i send post request using postman i can see the cookie and access token in headers but in my application i can't see anything in my localstorage&cookies
Here is my code
authContext.js
import axios from "axios";
import { createContext, useEffect, useState } from "react";
export const AuthContext = createContext();
export const AuthContextProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(
JSON.parse(localStorage.getItem("user")) || null
);
const login = async (inputs) => {
const res = await axios.post("http://localhost:8800/api/auth/login", inputs, {
withCredentials: true,
});
setCurrentUser(res.data)
};
useEffect(() => {
localStorage.setItem("user", JSON.stringify(currentUser));
console.log(currentUser);
}, [currentUser]);
return (
<AuthContext.Provider value={{ currentUser, login }}>
{children}
</AuthContext.Provider>
);
};
in login.jsx
const [inputs, setInputs] = useState({
username: "",
password: "",
});
const [err, setErr] = useState(null);
const navigate = useNavigate()
const handleChange = (e) => {
setInputs((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
const login = useContext(AuthContext);
const handleLogin = async (e) => {
e.preventDefault();
try {
await login(inputs);
navigate("/")
} catch (err) {
setErr(err.response.data);
}
};
console.log(err);
console.log(inputs);
I'm trying to solve the problem because i'm trying to create a basic social app i need accessToken to display posts in my feed easily
Related
so I'm having a problem getting data from my server to my front-end using axios.
as you can see in this picture I'm getting a response for the GET method for users/users.
this is my showUsers function
const showUsers = async (req, res) => {
await User.find({})
.then((user) => {
res.status(200).json(user);
})
.catch((error) => {
res.status(400).send(error);
});
};
this is my axios api export
import axios from "axios";
export default axios.create({
baseUrl: "http://localhost:8080/users",
});
and this is my useEffect
import api from "../api/users";
import { useState, useEffect } from "react";
export const LogIn = (props) => {
const { setIsNewMember } = props;
const [users, setUsers] = useState([]);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await api.get("/users");
setUsers(response.data);
} catch (err) {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
console.log(err.response.headers);
} else {
console.log(`Error: ${err.message}`);
}
}
};
fetchUsers();
}, []);
I'm getting this error on the frontend
so although I'm getting it from the postman and other services I'm not getting it on the front.
any idea why is that happening?
Context
I'm building a simple web application using the MERN stack for practice. In the app, logged-in users should be able to add a new blog to the site. However, for some reason my axios post request to the backend is failing and I'm receiving a 401 error. I'm using jsonwebtoken to handle the authentication. Submitting a POST request via Insomnia works fine so I don't believe it's an issue with my endpoint. I'm running backend server locally on my machine on port 3003 and have set up a proxy so there's no issues with cors. This works fine as the blogs from the backend are displays on the frontend once a user has logged in.
I've also checked the headers and can confirm that logged-in users have a valid bearer token.
What could be causing the issue?
Frontend
I can't post any images but here's a link to the frontend view:
https://imgur.com/a/DdUlfg9
App.js
import React, { useState, useEffect } from 'react'
import Blog from './components/Blog'
import blogService from './services/blogs'
import loginService from './services/login'
import LoginForm from './components/loginForm'
import BlogForm from './components/blogForm'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [errorMessage, setErrorMessage] = useState(null)
const [newBlog, setNewBlog] = useState({
title: '',
author: '',
url: ''
})
useEffect(() => {
blogService.getAll().then(blogs =>
setBlogs( blogs )
)
}, [])
useEffect(() => {
const loggedInUser = window.localStorage.getItem("loggedBlogUser")
if(loggedInUser){
const user = JSON.parse(loggedInUser)
setUser(user)
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password
})
window.localStorage.setItem(
'loggedBlogUser', JSON.stringify(user)
)
blogService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception){
setErrorMessage('Wrong credentials')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const handleLogout = async (event) => {
event.preventDefault()
if(user){
window.localStorage.removeItem("loggedBlogUser")
setUser(null)
}
}
const handleBlogField = (event) => {
event.preventDefault()
const {name, value} = event.target
console.log(newBlog.title)
setNewBlog(prevBlog => ({
...prevBlog,
[name] : value
}))
}
const addBlog = async (event) => {
event.preventDefault()
try {
const blog = await blogService.create(newBlog)
console.log("POST REQUEST: ",newBlog)
console.log('lets geddit')
setBlogs(blogs.concat(blog))
} catch (exception){
setErrorMessage('Uh oh, try again :[')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
if(user === null){
return(
<>
{errorMessage}
<h2>Log into application</h2>
<LoginForm handleLogin={handleLogin} setUsername={setUsername} setPassword={setPassword} username={username} password={password}/>
</>
)
}
return (
<div>
<h2>blogs</h2>
{user &&
<div>
<h3>{user.username} logged in</h3>
<button onClick={handleLogout}>Logout</button>
</div>
}
<BlogForm handleSubmission={addBlog} newBlog={newBlog} handleBlogField={setNewBlog}/>
{/* <BlogForm addBlog={addBlog} title={newBlog.title} setTitle={setTitle} setAuthor={setAuthor} author={newBlog.author} url={newBlog.url} setUrl={setUrl}/> */}
{blogs.map(blog =>
<Blog key={blog.id} blog={blog} />
)}
</div>
)
}
export default App
Blogs.js
import axios from 'axios'
const baseUrl = '/api/blogs'
let token = null
//let config
const setToken = (newToken) => {
token = `bearer ${newToken}`
}
const getAll = async () => {
const response = await axios.get(baseUrl)
return response.data
}
const create = async (newObject) => {
const config = {
headers: {
Authorization: token
}
}
const response = await axios.post(baseUrl, newObject, config)
console.log(`RESPONSE: ${newObject}`)
return response.data
}
const blogService = {
getAll, setToken, create
}
export default blogService
Have you configured CORS?, in order to accept your localhost requests?
myReactApp/functions/index.js
const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const stripe = require('stripe')
('sk_test_**********');
// API
// App config
const app = express();
// Middlewares
app.use( cors({origin:true}) );
app.use(express.json());
// API routes
app.get('/', (request, respond) => respond.status(200).send("page is working") );
app.post('/payment/create', async (request, response) => {
const total = request.query.total;//get the value of total from URL using query
console.log('payment request recived >>>' , total);
const paymentIntent = await stripe.paymentIntents.create({
amount: total,
currency: 'USD'
})
response.status(201).send({
clientSecret : paymentIntent.client_secret,
})
})
//http://localhost:5001/clone-21937/us-central1/api
// Listen command
exports.api = functions.https.onRequest(app);
myReactApp/src/payment.js
import React, { useEffect, useState } from 'react';
import Orders from './Orders';
import CheckoutProduct from './CheckoutProduct';
import CurrencyFormat from 'react-currency-format';
import { CardElement, useElements, useStripe } from '#stripe/react-stripe-js';
import { collection, addDoc, setDoc } from 'firebase/firestore/lite'
import { Link, useNavigate } from 'react-router-dom';
import { useStateValue } from './StateProvider';
import { db } from './firebase';
import axios from './axios';
const Payment = () => {
const stripe = useStripe();
const elements = useElements();
const navigate = useNavigate();
const [{ basket, subtotal, user }, dispatch] = useStateValue();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState('');
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
const getClientSecret = async () => {
const response = await axios({
method: 'POST',
url: `/payment/create?total=${subtotal * 100}`
});
//clientSecret is the amount to be paid
//fetching the clientSecret send from response (Index.js)
setClientSecret(response.data.clientSecret);
}
getClientSecret();
}, [basket]);
//handle submitting the form
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then( ({paymentIntent}) => {
console.log(paymentIntent);//undefined
try {
addDoc(
collection(db,'users', user?.uid, 'orders'),{
basket:basket
}
)
}
catch (error) {
alert(error.message);
}
//empty the basket after order
dispatch({
type: 'EMPTY_BASKET'
})
setSucceeded(true);
setProcessing(false);
setError(null);
// navigate('/orders');
})
}
const handleChange = (event) => {
setDisabled(event.empty);
setError(event.error ? event.error.message : '');
}
return (
<div className="payment_sectionTransaction">
<form onSubmit={handleSubmit}>
<CardElement className='payment_cardElement' onChange={handleChange}/>
<CurrencyFormat
value={subtotal}
prefix={'$'}
decimalScale={2}
thousandSeparator={true}
displayType={'text'}
renderText={(value) => {
return <>
<p><strong>Amount: {value}</strong></p>
</>
}} />
<button type='submit' disabled={processing || succeeded || disabled} >
{processing ? 'Processing..' : 'Confirm Order'}
</button>
</form>
</div>
)
}
export default Payment
After payment I am trying to get the response-paymentIntent but it shows to be undefined.
I can see the payment in the stripe dashboard so may be payment sections is all good but response after the payment is not good.
I also get this error in console after payment get done:
POST http://localhost:5001/clone-21937/us-central1/api/payment/create?total=0 net::ERR_FAILED 200
getClientSecret is async function. You must write code look like
const result = await getClientSecret();
Greetings I have a problem every time when I want to make an Admin REST API call to Shopify I get this problem "Error: Failed to parse session token '****' jwt expired" I see some code examples on the net I have my own custom session storage for accessToken and shop but every time when I try to call my own route from front-end and get more details about the shop I get this problem here is code example can anyone help me?
server.js
import "#babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import createShopifyAuth, { verifyRequest } from "#shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "#shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";
const helmet = require("koa-helmet");
const compress = require("koa-compress");
const cors = require("koa-cors");
const logger = require("koa-logger");
const bodyParser = require("koa-bodyparser");
import axios from "axios";
import { storeCallback, loadCallback, deleteCallback } from "./custom-session";
const sequelize = require("./database/database");
const { Shopify_custom_session_storage } = require("./../models/sequelizeModels");
// import apiRouter from "./../routers/apiRouter";
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
dev,
});
const handle = app.getRequestHandler();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\/|\/$/g, ""),
API_VERSION: ApiVersion.October20,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(storeCallback, loadCallback, deleteCallback)
});
sequelize.sync()
.then(() => {
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
server.keys = [Shopify.Context.API_SECRET_KEY];
server.use(
createShopifyAuth({
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const { shop, accessToken, scope } = ctx.state.shopify;
const host = ctx.query.host;
// Getting users data from database and saving it to variable //
try {
await Shopify_custom_session_storage.findAll({
raw: true,
where:{
shop: shop
},
limit:1
});
} catch(err) {
console.log(err);
throw err;
}
// End of Getting users data from database and saving it to variable //
const response = await Shopify.Webhooks.Registry.register({
shop,
accessToken,
path: "/webhooks",
topic: "APP_UNINSTALLED",
webhookHandler: async (topic, shop, body) =>{
return Shopify_custom_session_storage.destroy({
where: {
shop: shop
}
})
.then(result => {
return true;
})
.catch(err => {
if(err) throw err;
return false;
});
}
});
if (!response.success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
// Redirect to app with shop parameter upon auth
ctx.redirect(`/?shop=${shop}&host=${host}`);
},
})
);
const handleRequest = async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.post("/webhooks", async (ctx) => {
try {
await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
}
});
router.post("/graphql", verifyRequest({ returnHeader: true }), async (ctx, next) => {
await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
}
);
// Our Routes //
router.get("/getProducts", verifyRequest({ returnHeader: true }), async (ctx) => {
try{
const session = await Shopify.Utils.loadCurrentSession(ctx.req, ctx.res);
const client = new Shopify.Clients.Rest(session.shop, session.accessToken);
console.log(session);
}catch(err) {
console.log(err);
throw new Error(err);
}
});
// End of Our Routes //
router.get("(/_next/static/.*)", handleRequest); // Static content is clear
router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
router.get("(.*)", async (ctx) => {
const shop = ctx.query.shop;
try {
let user = await Shopify_custom_session_storage.findAll({
raw: true,
where:{
shop: shop
},
limit:1
});
// This shop hasn't been seen yet, go through OAuth to create a session
if (user[0].shop == undefined) {
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
} catch(err) {
console.log(err);
throw err;
}
});
server.use(router.allowedMethods());
server.use(router.routes());
// Setting our installed dependecies //
server.use(bodyParser());
server.use(helmet());
server.use(cors());
server.use(compress());
server.use(logger());
// End of Setting our installed dependecies //
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
})
.catch((err) => {
if(err) throw err;
return process.exit(1);
})
_app.js
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import App from "next/app";
import { AppProvider } from "#shopify/polaris";
import { Provider, useAppBridge } from "#shopify/app-bridge-react";
import { authenticatedFetch, getSessionToken } from "#shopify/app-bridge-utils";
import { Redirect } from "#shopify/app-bridge/actions";
import "#shopify/polaris/dist/styles.css";
import translations from "#shopify/polaris/locales/en.json";
import axios from 'axios';
function userLoggedInFetch(app) {
const fetchFunction = authenticatedFetch(app);
return async (uri, options) => {
const response = await fetchFunction(uri, options);
if (
response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
) {
const authUrlHeader = response.headers.get(
"X-Shopify-API-Request-Failure-Reauthorize-Url"
);
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
return null;
}
return response;
};
}
function MyProvider(props) {
const app = useAppBridge();
const client = new ApolloClient({
fetch: userLoggedInFetch(app),
fetchOptions: {
credentials: "include",
},
});
const axios_instance = axios.create();
// Intercept all requests on this Axios instance
axios_instance.interceptors.request.use(function (config) {
return getSessionToken(app) // requires a Shopify App Bridge instance
.then((token) => {
// Append your request headers with an authenticated token
config.headers["Authorization"] = `Bearer ${token}`;
return config;
});
});
const Component = props.Component;
return (
<ApolloProvider client={client}>
<Component {...props} axios_instance={axios_instance}/>
</ApolloProvider>
);
}
class MyApp extends App {
render() {
const { Component, pageProps, host } = this.props;
return (
<AppProvider i18n={translations}>
<Provider
config={{
apiKey: API_KEY,
host: host,
forceRedirect: true,
}}
>
<MyProvider Component={Component} {...pageProps} />
</Provider>
</AppProvider>
);
}
}
MyApp.getInitialProps = async ({ ctx }) => {
return {
host: ctx.query.host,
};
};
export default MyApp;
index.js
import { Heading, Page, Button } from "#shopify/polaris";
function Index(props){
async function getProducts(){
const res = await props.axios_instance.get("/products");
return res;
}
async function handleClick() {
const result = await getProducts();
console.log(result);
}
return (
<Page>
<Heading>Shopify app with Node and React </Heading>
<Button onClick={handleClick}>Get Products</Button>
</Page>
);
}
export default Index;
I found the solution for "Error: Failed to parse session token '******' jwt expired" the problem was Computer Time was not synchronized, check the computer time and synchronized it, for my example, I'm on Kali Linux and I search it how to synchronize time on Kali Linux and follow that tutorial when you finally synchronize your time restart your application server and try again. That's it so dump I lost 4 days on this.
I did a REST api using node.js and express, I started trying to build user authentication so I used JWT. Now, I'm trying to build a React Native application, but keep getting Error 401 Access Denied. Here's where I receive the JWT token:
...
import api from '../services/api';
export default function Login({ navigation }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
useEffect(() => {
AsyncStorage.getItem('authToken').then(authToken => {
if (authToken) {
navigation.navigate('Dashboard');
}
});
}, []);
async function handleSubmit() {
try {
const response = await api.post('/login', {
email,
password
});
const authToken = response.data;
await AsyncStorage.setItem('authToken', response.data);
if (authToken) navigation.navigate('Dashboard');
} catch (err) {
}
}
...
Here's where I need authentication, but I can't seem find out how to send authToken and get response from the api.
...
import api from '../services/api';
export default function List({ navigation }) {
useEffect(() => {
AsyncStorage.getItem('authToken').then(authToken => {
if (!authToken) {
navigation.navigate('Login');
}
});
}, []);
async function handleSubmit() {
const response = await api.post('/tasks', {
"description": "Finish this shit",
"priority": 3,
"completed": false
});
console.log(response.data);
}
...