Problems Retrieving JWT from AsyncStorage to Create httpLink Middleware with ApolloClient - javascript

I'm pretty much copy/pasting the example code from the Apollo GraphQL Network Layer Docs on Creating Middleware, except I'm pulling my dependencies from apollo-client-preset and I'm using a simple utility library to return the jwt token. Here's the link code...
import { ApolloClient, HttpLink, InMemoryCache, ApolloLink, concat } from 'apollo-client-preset';
import { getSessionToken } from './api/localStorage';
const httpLink = new HttpLink({ uri: 'http://localhost:4000/' });
const authMiddleware = new ApolloLink((operation, forward) => {
const token = getSessionToken();
const authorizationHeader = token ? `Bearer ${token}` : null;
operation.setContext({
headers: {
authorization: authorizationHeader,
}
});
return forward(operation);
})
const client = new ApolloClient({
link: concat(authMiddleware, httpLink),
});
And here's the ./api/localStorage method in play...
export const getSessionToken = () => {
return AsyncStorage.getItem(AUTH_TOKEN);
}
Executing the above code results in an HTTP request with the following headers...
POST / HTTP/1.1
Host: localhost:4000
Content-Type: application/json
User-Agent: Expo/2.2.0.1011489 CFNetwork/893.14 Darwin/17.3.0
Connection: keep-alive
Accept: */*
Accept-Language: en-us
Authorization: Bearer [object Object]
Accept-Encoding: gzip, deflate
Content-Length: 174
Notice the Authorization: Bearer [object Object] bit
I think the problem is pretty obvious. AsyncStorage is an async function, and I need to wait for the promise to be resolved before I assemble the authorization string. The solution, however, is less obvious. I've tried various methods, but no love so far.
I've seen a couple examples similar to the above. Here's another in the How to GraphQL Authentication Module. Neither shows how to wait for the asyncstorage promise to resolve first. I know Apollo waits for the promises for you automagically sometimes, so I thought that might be the case here. But doesn't seem to be in my experience.
So what's the solution?
Here's a couple things I've tried, but that have failed.
1. Promise.then()
const middlewareAuthLink = new ApolloLink((operation, forward) => {
getSessionToken().then(token => {
const authorizationHeader = token ? `Bearer ${token}` : null
operation.setContext({
headers: {
authorization: authorizationHeader
}
})
});
return forward(operation)
})
This does construct the authorization string properly, but doesn't seem to create the middleware because this does not create the authorization header. To me, this seems like my best bet, but I must be doing it wrong for reasons which are not obvious to me.
POST / HTTP/1.1
Host: localhost:4000
Content-Type: application/json
Connection: keep-alive
Accept: */*
User-Agent: Expo/2.2.0.1011489 CFNetwork/893.14 Darwin/17.3.0
Content-Length: 174
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Notice the lack of Authorization header
2. async/await
I thought this would be pretty straight forward, turning this into an async/await function, but not so much. Here's the code
const middlewareAuthLink = new ApolloLink(async (operation, forward) => {
const token = await getSessionToken();
const authorizationHeader = token ? `Bearer ${token}` : null;
operation.setContext({
headers: {
authorization: authorizationHeader,
}
});
return forward(operation)
})
But that resulted in this super ugly red-screen-of-death error...
Unhandled (in react-apollo:Apollo(EventList)), ApolloError#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:106405:36
currentResult#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:106516:43
dataForChild#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:101608:79
render#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:101659:49
finishClassComponent#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:4528:102
performUnitOfWork#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:5547:33
workLoop#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:5566:142
_invokeGuardedCallback#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2707:23
invokeGuardedCallback#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2681:41
performWork#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:5602:41
scheduleUpdateImpl#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:5723:105
enqueueForceUpdate#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:4341:179
forceUpdate#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:8265:38
forceRenderChildren#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:101579:58
next#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:101554:50
error#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:109797:25
forEach#[native code]
error#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:106747:44
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:107277:47
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:107649:29
forEach#[native code]
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:107648:27
forEach#[native code]
broadcastQueries#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:107644:33
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:107239:51
tryCallOne#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:10901:14
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:10987:25
_callTimer#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:12157:15
_callImmediatesPass#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:12193:17
callImmediates#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:12397:31
__callImmediates#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2301:30
http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2179:32
__guard#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2287:11
flushedQueue#http://localhost:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/ChrisGeirman/dev/mobile/playground/exp/frogquest-app/node_modules/expo/tools/hashAssetFiles:2178:19
flushedQueue#[native code]
invokeCallbackAndReturnFlushedQueue#[native code]
So how do I wait for the result of AsyncStorage to return before setting the header?

There may be other solutions, or better solutions even, but this finally worked for me so I'm posting it as solved.
import { setContext } from 'apollo-link-context';
const httpLink = new HttpLink({ uri: 'http://localhost:4000/'});
const authHeader = setContext(
request =>
new Promise((success, fail) => {
getSessionToken().then(token => success({ headers: { authorization: `Bearer ${token}` }}))
})
)
const client = new ApolloClient({
link: concat(authHeader, httpLink),
cache: new InMemoryCache(),
})

Here is an alternative which loads the token from an in memory cache which should perform better than fetching from AsyncStorage. Alternatively you could simply have a getter wrapper function which caches the response from AsyncStorage but having this as part of apollo cache has the added benefit of re-rendering when you update the token.
import gql from 'graphql-tag'
import ApolloClient from 'apollo-client'
import { setContext } from 'apollo-link-context'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
import AsyncStorage from '#react-native-community/async-storage'
const authLink = setContext(async (_, { headers }) => {
const context = await client.query({
query: gql`
query AuthQuery {
authToken #client
}
`
})
const {
data: { authToken: token }
} = context
let extra = {}
if (token) {
extra = { authorization: `Bearer ${token}` }
}
return {
headers: {
...headers,
...extra
}
}
})
const httpLink = createHttpLink({
uri: 'http://localhost:4000/'
})
const cache = new InMemoryCache()
const client = new ApolloClient({
link: ApolloLink.from([authLink, httpLink]),
cache
})
client.writeData({ data: { authToken: null } })
AsyncStorage.getItem('token').then((token: string | null) => {
if (token) {
client.writeData({ data: { authToken: token } })
}
})
export { client }

Related

Set-Cookie not working properly in axios call

Explanation
here, I sent one get req to ABC.com/Users/Login using Axios after this I sent a post request to ABC.com/Users/Login with form data and Cookie.
but it does not work properly. It works properly in postmen
My Code
axios.get('ABC.com/Users/Login')
.then(async response => {
console.log("call login page");
let tokenKey = "__RequestVerificationToken";
let tokenValue = "CfDJ8DF1Ubmz1lpEibYtvvnYRTVXaJ-HWILEtqE_A3bGmDrD-yyKyJPbYK7qrcS9AIzezPo5-
tOWmcXs6WgYThZP-5qo1o1XXpalkJDEPnBtnVa7EhaUYbY2XNcANuugyWgkIf3-O2-_f5h7mNu960qGIaM";
const userName="XYZ";
const pass="test#123";
let form=new FormData();
form.append('UserName', userName);
form.append('Password', pass);
form.append([tokenKey], tokenValue);
headers={
'Cookie':response.headers['set-cookie'];
}
await axios.post('ABC.com/Users/Login', form,
{ headers: {...form.getHeaders(),...headers}})
.then(async response => {
console.log(`Login success in ${userName}`);
console.log("response",response.data);
})
.catch(error => {
console.log(error);
});
}
.catch(error => {
console.log(error);
});
In the First Axios call, I got:-
Set-Cookie: .AspNetCore.Antiforgery.b02ILwhXMuw=CfDJ8DF1Ubmz1lpEibYtvvnYRTXz_0rOkGhY6OXEw3d3vsDNG81V4IaMPfVZm5Hk3_icgp_ToLDG9xKu2mcM1VtEOMnSCktfZwG7Dj9_549SUiKht6Yv33pozagGjseFsfXI74wBwu-mMJkzgwfPx3jS4OA; path=/; samesite=strict; httponly
Set-Cookie: ABC.Session=CfDJ8DF1Ubmz1lpEibYtvvnYRTViv4PoRc%2F7jhjXdtCo4m1GZbcMf60xe9sOva27QUGL0BvT2A2SQZaCmrXlj%2FVL9lTvower%2B1lF87MQVTwDQKAFoEODlnPfWEM6SsrqDa0tomlRynXOtyCROBltiwNI27vo3uo4Y8jEn834lZ4OHYG3; path=/; samesite=lax; httponly
I Want to set cookie like this :-
Cookie: .AspNetCore.Antiforgery.b02ILwhXMuw=CfDJ8DF1Ubmz1lpEibYtvvnYRTXz_0rOkGhY6OXEw3d3vsDNG81V4IaMPfVZm5Hk3_icgp_ToLDG9xKu2mcM1VtEOMnSCktfZwG7Dj9_549SUiKht6Yv33pozagGjseFsfXI74wBwu-mMJkzgwfPx3jS4OA; ABC.Session=CfDJ8DF1Ubmz1lpEibYtvvnYRTViv4PoRc%2F7jhjXdtCo4m1GZbcMf60xe9sOva27QUGL0BvT2A2SQZaCmrXlj%2FVL9lTvower%2B1lF87MQVTwDQKAFoEODlnPfWEM6SsrqDa0tomlRynXOtyCROBltiwNI27vo3uo4Y8jEn834lZ4OHYG3
It works in postmen but not in Axios call. Even I used this also but its not working
let cook1 = response.headers['set-cookie'][0].replace(" path=/; samesite=strict; httponly", "");
let cook2 = response.headers['set-cookie'][1].replace("; path=/; samesite=lax; httponly", "");
let mainCookie=cook1 + " " + cook2
// mainCookie .AspNetCore.Antiforgery.b02ILwhXMuw=CfDJ8DF1Ubmz1lpEibYtvvnYRTUh3vyphSzebPn04M1GqaH8KdFgWLSBpj5a06HBUhoYBhWdiWJw7Yy5525ZcZ_WblCjF7AzWbhQl2dFbQTwOmzP3K7oa0CLirsSJYkhIG-fHGizaNo-3cf8YdSiECkGhMM; ABC.Session=CfDJ8DF1Ubmz1lpEibYtvvnYRTVEF0LnEGw51HveT2mRMrzmgbHiPWjs8UiPcGcqUpJBhTG1uBSE5NLG8tBwkW1XcJH3OxPcPPsaB30aaRREgroCkO1jw%2BJY6tavDFE0P9RTmk9%2Bf2CTVwaTWYRQgPGam1CWJfODoyCzHwiIdfl8ciJS
headers={
'Cookie':mainCookie;
}
If you are using axios, set withCredentials to true.
Example:
const api = axios.create({
baseURL: "http://localhost:5000/api/v1",
withCredentials: true,
headers: {
"Content-type": "application/json",
},
});
then in your Node, in cors middleware, set
app.use(
cors({
credentials: true,
origin: "http://localhost:3000",
})
);
If you want to use Cookies with Axios you need to include the withCredentials property.
axios.post('ABC.com/Users/Login', form, { withCredentials: true });
If it were me I would create a new axios instance and use that one for your calls so that its the same instance of axios for all your api calls.
const axiosInstance = axios.create({
withCredentials: true
})
axiosInstance.post('ABC.com/Users/Login', form)

How can i create an axios instance on Next.js?

I am trying to create and axios instance so that I don't have to write Authorization header on every request. I am storing access token on localStorage.
I tried creating a file axiosInstance.ts
import axios, { AxiosInstance } from "axios"
const service = axios.create({
baseURL: "http://localhost:5000/",
headers: {
Authorization: localStorage && localStorage.getItem("token")
? `Bearer ${localStorage.getItem("token")}`
: "",
},
})
export default service
But it throws localStorage is not defined error.
So I tried to make this a custom hook like this
useAxios.ts
function useAxios() {
const [axiosInstance, setAxiosInstance] = useState<null | AxiosInstance>(null)
useEffect(() => {
const service = axios.create({
baseURL: "http://localhost:5000/",
headers: {
Authorization: localStorage.getItem("token")
? `Bearer ${localStorage.getItem("token")}`
: "",
},
})
setAxiosInstance(service)
}, [])
return axiosInstance
}
export default useAxios
And when i tried to use it like this it threw an error which says service.post is not a function
So when i log the service/axiosInstance it logs a get request promise to baseURL. I am not sure what i am doing wrong.

GetResponse 400 Bad Request

I'm trying to send a POST method to https://api.getresponse.com/v3/contacts from my Vue using axios. I'm unsure why I kept getting a 400 Bad Request. I've tried checking the Network tab on Mozilla dev tools but there doesn't seem to have any Response message it just returned me.
XHR OPTIONS https://api.getresponse.com/v3/contacts [HTTP/1.1 400 Bad Request 763ms]
I have double confirm from GetResponse documentation to add the Content-Type header to application/json and to set my API key as X-Auth-Token: api-key <API_KEY>.
NOTE: I am also getting CORS header ‘Access-Control-Allow-Origin’ missing but I believe it does not have anything to do with the Error 400.
Here are some code snippets from my Vue file.
axios-config.js
const instance = axios.create({
baseURL: process.env.VUE_APP_GET_RESPONSE_BASE_URL,
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': `api-key ${process.env.VUE_APP_GET_RESPONSE_API_KEY}`,
}
});
Vue
import axios from "#/services/axios-config.js";
user: {
name: "",
campaign: {
campaignId: `${process.env.VUE_APP_GET_RESPONSE_CAMPAIGN_ID}`
},
email: "",
customFieldValue: {
customFieldId: "interest",
value: []
}
}
async callSubscribeAPI() {
try{
const response = await axios.post("/contacts",this.user);
console.log(response);
}catch(error){
console.log("error");
console.log(error);
}
}
This works for me:
(async() => {
const url = 'https://api.getresponse.com/v3/accounts';
const payload = await axios({
method: 'get',
url,
headers: {
"X-Auth-Token": "api-key 12345*****",
"content-type": "application/json"
}
});
console.log("payload", payload.data);
})()

React, axios, content-type

I have already searched a lot, but none of the solutions found work: Cannot send content-type by axios. but if I use the postman interceptor and I 'send' the request generated by axios this time it works: the node.js / express server correctly receives the request and body-parser works normally!
React side:
const API_URL = "http://localhost:8800/auth/";
const headers = {
accept: 'application/json, text/plain, */*',
'content-type': 'application/json;charset=UTF-8'
};
class AuthService {
register(pseudo, email, password) {
return axios.post(API_URL + "signup/",
{ pseudo, email, password },
{ headers: headers})
.then(response => {
if (response.data.accessToken) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
});
}
server side
const app = express();
app.use(function (req, res, next) {
console.log( req.headers);
next();
});
app.use( bodyParser.urlencoded({ extended: true }), bodyParser.json());
Usually when I use axios I send the headers in a config variable like this and I stringify the body so it sends as JSON object and not a JS object.
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({arguments});
try {
const res = await axios.post(/url, body, config);
...
Here's a link to the docs for a little more reading about it:
https://github.com/axios/axios

token is missing in my vue app

I have this response with httpie when an user is logged:
chat-api$ http :3000/signup username=tomatito password=123
HTTP/1.1 201 Created
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"01dfe24bd7415e252b5aee50e12198a3"
Transfer-Encoding: chunked
Vary: Origin
X-Request-Id: a095148b-592a-4347-820f-63e1efa0e409
X-Runtime: 0.347726
{
"auth_token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1LCJleHAiOjE1MjEzMTg4NDV9.45JDA7vk-K8gUzCB1xABKMifi-IWGoVESedKykGiqGo",
"message": "Account created successfully"
}
The object is persisted in my database.
However when i make this request with axios from my vue.js form I get nothing in localStorage
this is my axios.js code:
import axios from 'axios'
const API_URL = process.env.API_URL || 'http://localhost:3000/'
export default axios.create({
baseURL: API_URL,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.auth_token
}
})
the object is persisted in database right but i get Authorization:Bearer undefined
these are my headers:
Response:
Access-Control-Allow-Methods:GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin:http://localhost:8081
Access-Control-Expose-Headers:
Access-Control-Max-Age:1728000
Cache-Control:max-age=0, private, must-revalidate
Content-Type:application/json; charset=utf-8
ETag:W/"fdac439f3ada9e343d0815bb49dff277"
Transfer-Encoding:chunked
Vary:Origin
X-Request-Id:9e318050-ceca-480c-a847-d59f9ebb18b7
X-Runtime:0.447976
Request:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Authorization:Bearer undefined
Connection:keep-alive
Content-Length:44
Content-Type:application/json
Host:localhost:3000
Origin:http://localhost:8081
Referer:http://localhost:8081/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.
Request payload
{username: "tomatito", password: "123456"}
password:"123456"username:"tomatito"
This is my vue script component:
<script>
export default {
name: 'SignUp',
data () {
return {
username: '',
password: '',
error: false
}
},
methods: {
signup () {
this.$http.post('/signup', { username: this.username, password: this.password })
.then(request => this.signupSuccessful(request))
.catch(() => this.signupFailed())
},
signupSuccessful (req) {
if (!req.data.token) {
this.signupFailed()
return
}
localStorage.token = req.data.token
this.error = false
this.$router.replace(this.$route.query.redirect || '/rooms')
},
signupFailed () {
this.error = 'Sign up failed!'
delete localStorage.token
}
}
}
</script>
I'm getting Sign up failed, However the object is persisted in database. My back-end is ruby on rails. How can i receive in my data.token in payload?
This is my main.js file
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from './backend/vue-axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
axios,
template: '<App/>'
})
This is my vue-axios/index.js file:
import Vue from 'vue'
import VueAxios from 'vue-axios'
import axios from './axios'
Vue.use(VueAxios, axios)
Updated The problem was in req. it's res to receive the token instead of req
signup() {
this.$http
.post("/signup", { username: this.username, password: this.password })
.then(res => this.signupSuccessful(res))
.catch(() => this.signupFailed());
},
signupSuccessful(res) {
if (!res.data.auth_token) {
this.signupFailed();
return;
}
this.error = false;
localStorage.token = res.data.auth_token;
this.$store.dispatch("login");
this.$router.replace(this.$route.query.redirect || "/rooms");
},
.
.
.
.
Thank you
Try to set the token on every request with axios.interceptors
Put this on the main.js file so everywhere you import axios will have the config
axios.interceptors.request.use(config => {
const token= localStorage.getItem('my-token-key') // or where you have the token
config.headers.common['Authorization'] = 'Bearer ' + token
// you must return the config or it will not work
return config
})
I think that the problem is that axios.create instance is executed (created) just 1 time (then reference it), and not every time you import it, so if there was no token when the instance was created it will not work
Updated The problem was in req. it's res to receive the token instead of req
signup() {
this.$http
.post("/signup", { username: this.username, password: this.password })
.then(res => this.signupSuccessful(res))
.catch(() => this.signupFailed());
},
signupSuccessful(res) {
if (!res.data.auth_token) {
this.signupFailed();
return;
}
this.error = false;
localStorage.token = res.data.auth_token;
this.$store.dispatch("login");
this.$router.replace(this.$route.query.redirect || "/rooms");
},
.
.
.
.

Categories

Resources