i get a Cannot GET /api/auth/signup error every time i try to POST i cant figure it out why
can someone help me with this thanks very much i dont understand what im missing im tryning to post the register in the node js but it keeps telling me Cannot GET /api/auth/signup
auth.js
import axios from "axios";
const API_URL = "http://localhost:8080/api/auth/";
class AuthService {
async login(username, password) {
console.log(username, password);
return axios
.post(API_URL + "signin", {
username,
password,
})
.then((response) => {
if (response.data.accessToken) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
});
}
async logout() {
localStorage.removeItem("user");
}
async register(username, email, password) {
return axios.post(API_URL + "signup", {
username,
email,
password,
});
}
getCurrentUser() {
return JSON.parse(localStorage.getItem("user"));
}
}
export default new AuthService();
server.js
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
var corsOptions = {
origin: "http://localhost:8080",
};
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "it works." });
});
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
It appears you are attempting to POST to a route that doesn't exist. You will need to build out your /api/auth/signup route in order to send a request to it from axios.
// simple example of post route
app.post("/api/auth/signup", (req, res) => {
const { username, email, password } = req.body;
// Your logic to register user in your database
// Send response after database interaction
res.status(201).json({ message: 'User signed up for service' })
});
For each Specific route you need to implement respective route in your application.
In your application, if you need to have access to two post request of different url, you need to handle two post route.
For`/api/auth/signin`
app.post('/api/auth/signin', (req, res)=>{
//Your Implementation here
res.status(201).json({message: 'Your Message'})
})
For`/api/auth/signup`
app.post('/api/auth/signup', (req, res)=>{
//Your Implementation here
res.status(201).json({message: 'Your Message'})
})
Related
Im learning to use JWT. I setup a very simple react app and an express server that uses a json file as database to try it but when i return a cookie via res.cookie the request is stuck on pending according to my browsers network tab.
This is how my server looks
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const jwt = require("jsonwebtoken");
const { JsonDB, Config } = require("node-json-db");
require("dotenv").config();
const server = express();
server.use(express.json());
server.use(cors());
server.use(cookieParser());
const db = new JsonDB(new Config("db", true, false));
server.post("/login", async (req, res) => {
const { username, password } = req.body;
const data = await db.getData("/users");
const user = data.find((user) => {
return user.username === username && user.password === password;
});
if (!user) {
return res.status(403).json({
error: "invalid login",
});
}
const token = jwt.sign(user, process.env.MY_SECRET, { expiresIn: "1h" });
return res.cookie("token", token, { httpOnly: true });
});
server.get("/logout", (req, res) => {
console.log("cleared token");
return res.clearCookie("token");
});
server.listen(3000, () => {
console.log("server listening on port 3000");
});
And this is my request in my react app
const handleSubmit = async () => {
const username = usernameRef.current.value;
const password = passwordRef.current.value;
const response = await axios.post("http://localhost:3000/login", {
username: username,
password: password,
});
console.log(response);
};
I've tried changing the order of the middlewares around and adding next() at the end but didn't work. Sending data via res.send works just fine. I've worked with express about a year ago but never ran into this.
res.cookie only set cookie. It doesn't response to client. After res.cookie, use res.send, res.json or any method to response.
I'm building a React-Node app to consume QuickBooks APIs using OAuth 2 authentication. The app is structured so that the react app runs off a dev server at localhost:3000, and proxies http requests to the express server at localhost:3001.
So, I'm having some trouble making API calls: the react component responsible for rendering API data is crashing, and I'm getting the following error
"Missing required parameter: access_token"
I have the following code in my express server, which converts the authorization code into an access token, and then (I think) passes that token to http://localhost:3000/companyInfo. However I suspect this is where the problem is - is the token actually being sent to this address, or have I misunderstood how OAuth works? Here's the server-side code in question:
app.get("/callback", function (req, res) {
oauthClient
.createToken(req.url)
.then(function (authResponse) {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
})
.catch(function (e) {
console.error(e);
});
res.redirect("http://localhost:3000/companyInfo" );
});
...here's my entire server:
const express = require("express");
const OAuthClient = require("intuit-oauth");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const port = process.env.PORT || 3001;
let urlencodedParser = bodyParser.urlencoded({ extended: true });
let oauth2_token_json = null;
let oauthClient = null;
app.get("/authUri", urlencodedParser, (req, res) => {
oauthClient = new OAuthClient({
clientId: "****",
clientSecret: "****",
environment: "sandbox",
redirectUri: "http://localhost:3001/callback",
});
let authUri = oauthClient.authorizeUri({
scope: [OAuthClient.scopes.Accounting],
state: "testState",
});
res.send(authUri);
});
app.get("/callback", function (req, res) {
oauthClient
.createToken(req.url)
.then(function (authResponse) {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
})
.catch(function (e) {
console.error(e);
});
res.redirect("http://localhost:3000/companyInfo" );
});
app.get("/getCompanyInfo", (req, res) => {
let companyID = oauthClient.getToken().realmId;
let url =
oauthClient.environment == "sandbox"
? OAuthClient.environment.sandbox
: OAuthClient.environment.production;
oauthClient
.makeApiCall({
url: url + "v3/company/" + companyID + "/companyinfo/" + companyID,
})
.then(function (authResponse) {
console.log(
"The response for API call is :" + JSON.stringify(authResponse)
);
res.send(JSON.parse(authResponse.text()));
})
.catch(function (e) {
console.error(e);
});
});
app.listen(port, () => {
console.log(`Server is listening on port: ${port}`);
});
...and here's the react component where I want to render the returned API call data:
import React, { useState, useEffect } from 'react'
import axios from 'axios'
const CompanyInfo = () => {
const [ info, setInfo ] = useState('')
useEffect(() => {
axios.get('/getCompanyInfo')
.then(res => setInfo(res.data))
},[])
return(
<div>
<p> {info.CompanyInfo.CompanyName} </p>
</div>
)
}
export default CompanyInfo
The strange this is that sometimes I have been able to render the API call data in this component, but I can only do it once. If I refresh my page, it crashes, and I have to start the login process again in order to make the API call work.
I am new to server-side programming.
I am trying to serve a HTML file (mapview.html) after authentication ,but it does not appear without any error.
there is no problem with authentication process. I expect when I click on login button, the codes check req data
and after validating, mapview.html pop up but nothing happen.
res.sendFile() causes in jquery part, console.log(res), get me all html codes in console line of chrome.
files directory:
src
index.js
db
public
index.html
mapview.html
middleware
auth.js
routers
user
task
model
user
task
index.html
$('div[name="logIn"]').click( () => { // select a div element that its name is logIn
console.log('LOG-IN:')
$.ajax({
url: '/login',
data: $('#loginForm').serialize(), // Get email and pass from login form
type: 'POST',
success: function (res) {
console.log(res)
}
})
})
user.js
router.post('/login', async (req, res) => {
try {
const user = await User.findByCredentials(req.body.email, req.body.password)
const token = await user.generateAuthToken()
const publicDir = path.join(__dirname, '../public')
res.sendFile(path.join(publicDir + '/mapview.html'));
} catch (e) {
res.status(400).send(e)
}
})
index.js
const express = require('express');
require('./db/mongoose');
const bodyParser = require('body-parser');
const userRouter = require('./routers/user');
const taskRouter = require('./routers/task');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json()); // Parse recieved json body data from Postman
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
app.use(userRouter);
app.use(taskRouter);
app.listen(port, () => {
console.log('server is run on port:' + port)
});
when you are making the HTTP post request from index.html using ajax to verify user authentication details, on successful authentication you are sending a static html file which is simply a text response and will not be rendered as a web page (as you were expecting).
To solve this problem,
Create a separate route for accessing the mapview.html
app.get('/map', (req, res) => {
res.sendFile(__dirname + '/public' + '/mapview.html');
});
In your ajax response just redirect to the map route
$.ajax({
url: '/login',
data: $('#loginForm').serialize(), // Get email and pass from login form
type: 'POST',
success: function (res) {
console.log(res);
window.location.href = '/map'; // redirect to map route
}
});
I updated the codes and it looks like following code .
As I mention in the past comment , I need to authenticate before refirect through .href = '/map' and I do not know how to attach token to .href='/map.
we usually send token as header with ajax like this:
headers:{"Authorization": localStorage.getItem('token')}
in case I add it to .href ,something like this window.location.href = '/map + "?token=MY_TOKEN" , how can i get it in auth method?
user.js
router.post('/login', async (req, res) => {
try {
const user = await User.findByCredentials(req.body.email,
req.body.password)
const token = await user.generateAuthToken()
res.send({user, token})
} catch (e) {
res.send(e)
res.status(400).send(e)
}
})
router.get('/map', auth, (req, res) => {
const publicDir = path.join(__dirname, '../public')
res.sendFile(path.join(publicDir + '/mapview.html'));
});
index.html
$('div[name="logIn"]').click( () => {
$.ajax({
url: '/login',
data: $('#loginForm').serialize(),
type: 'POST',
success: function (res) {
localStorage.setItem('token', res.token);
window.location.href = '/map';
}
})
})
I am using node and express with vue. I try to implement a middleware for my node routes, to check the login token and if it is wrong, redirect to the login page.
This is my code so far.
Main app.js file
const express = require('express');
const path = require('path');
const cors = require('cors');
const http = require('http');
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(express.static(path.join(__dirname,'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use('/login', require('./routes/login'));
app.use('/performance', require('./routes/performance'));
const port = 4000;
http.createServer(app).listen(port, ()=>{
console.log('server runs on port ', port);
});
Then in my routes I have
const express = require('express');
const token = require('../../lib/token');
router.get('/:product/dataquality/', token.validate(), (req, res)=>{
const product = req.params.product;
db.dataquality(product)
.then((resolved)=>{
console.log('route dataquality result', resolved);
res.json({success:true, data:resolved});
})
.catch((error)=>{
console.log('route dataquality error', error);
res.json({success:false, data:false});
});
});
And this token.validate middleware is
const jwt = require('jsonwebtoken');
const config = require('../db/config');
const validate = ()=>{
return (req, res, next)=>{
const token = req.get('Authorization');
const key = config.key;
jwt.verify(token, key,function(err, decoded) {
if (err){
console.log('token error');
res.redirect('/login');
}
if (decoded){
console.log('token ok');
next();
}
});
}
}
exports.validate = validate;
This works fine and I see the token console logs when I login in my app. If I go to the browser and edit the token (delete a couple of characters, but not completely remove it) so the token is there but is the wrong token, it has the wrong value :
I see in my console token error and I get no data, but the redirect to login page never happens.
If I do res.redirect('http://localhost:8080/login'); I still get no redirect.
What am I missing? How can I fix this?
If you think this is a Vue issue, let me know, so I can provide Vue routing code.
Thanks
EDIT
This the file that handles routes in Vue - router.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '#/components/store';
import Login from './components/Login.vue'
import Performance from './views/Performance.vue'
Vue.use(Router)
const router = new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: '/login',
name: 'login',
component: Login,
},
{
path: '/performance',
name: 'performance',
component: Performance,
beforeEnter: (to, from, next) => {
if (store.state.login.token == null || !store.state.login.token) {
next('/login');
}
else{next();}
}
},
{
path: '*',
redirect: '/login'
}
]
})
router.beforeEach((to, from, next) => {
store.dispatch('resetAccessToken');
if (to.fullPath === '/performance') {
if (!store.state.login.token) {
console.log('VUE route go to login');
next('/login');
}
}
if (to.fullPath === '/login') {
if (store.state.login.token) {
console.log('VUE route browse normally');
next('/performance');
}
}
next();
});
If I search for "route" in my browser console to find console.log('VUE route go to login'); or console.log('VUE route browse normally'); it says it found 160 but I cannot see none.
I still get no data, but I can browse normally to empty Vue pages. Node or Vue redirect should work and send me to login , but none works, so I still can browse around.
Thanks
I'm trying to make a simple POST request but I'm getting an empty response back from the server. I've sifted through all the SO questions regarding this topic and tried the solutions posted but to no avail.
I've tried changing the request header options to use 'application/x-www-form-urlencoded' and set bodyParser in my express app as app.use(bodyParser.urlencoded({ extended: true })); but that didn't work either.
auth-service.service.ts
login(loginInfo: object) {
return this.http.post<loginInfo>(this.loginUrl, { "test": "test" })
.pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.log('An error occured:', error.error.message);
} else {
console.log(`Backend returned code ${error.status}, ` +
`body was ${error.error}`);
}
return throwError('Something bad happened; please try again later.')
}
login.component.ts (calls the login service method)
onSubmit() {
const loginInfo = { username: this.username.value, password: this.password.value };
this.authService.login(loginInfo).subscribe(
resp => { console.log(resp); },
err => { console.log(err); }
)
}
server.js (I've defined routes here but they're not relevant)
const express = require('express');
const bodyParser = require('body-parser');
const api = require('./routes/api');
const app = express();
const port = process.env.port || 3000;
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
})
app.use(bodyParser.json());
app.use('/api', api)
app.get('/', function (req, res) {
res.send(JSON.stringify('Hello from server'));
})
app.post('/login', (req, res) => {
let userData = req.body
res.send('Request body: ' + JSON.stringify(userData));
})
app.listen(port, function () {
console.log('Server running on localhost: ' + port);
});
I'm console logging the following:
Backend returned code undefined, body was undefined
Something bad happened; please try again later.
When I try using Postman, however, I get the response I expect (i.e. Request body: {})
I'm not sure as to why a response is retrieved when done through Postman but not when done through the app.
Any help is appreciated. Thanks!
You need to set body for POST request in auth-service.service.ts:
import { HttpParams } from '#angular/common/http';
login(loginInfo: object) {
const body = new HttpParams()
.set('test', 'test');
return this.http.post<loginInfo>(this.loginUrl, body)
.pipe(
catchError(this.handleError)
);
}
try using express.json its missing
app.use(express.json());
and
app.use(bodyParser.urlencoded({
extended: true
}));