I have written the following function in js to verify a ReCAPTCHA token:
export async function validateHuman(token) {
const secret = "funny_little_secret";
const response = await fetch(
"https://www.google.com/recaptcha/api/siteverify?secret=" +
secret +
"&response=" +
token,
{ method: "POST" }
);
const data = response.json();
return data.success;
}
For reasons I do not understand, I get a fetch error while running this. I have looked in to a few other versions of the functions but have not yet found a solution.
Moreover, the token is correct and is produced according to the documentation, so I am wondering whether there is something wrong about my secret, as I have seen others use something along the lines of process.env.secret, which I have tried without success, or it there is something I do not understand about the fetch function.
This is the complete error:
Uncaught TypeError: Failed to fetch
validateHuman # http://localhost:3000/static/js/bundle.js:3384:26
thanks in advance
Related
In the Apollographql documentation it states:
The onError link can retry a failed operation based on the type of GraphQL error that's returned. For example, when using token-based authentication, you might want to automatically handle re-authentication when the token expires.
This is followed up by their sample code:
onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
for (let err of graphQLErrors) {
switch (err.extensions.code) {
// Apollo Server sets code to UNAUTHENTICATED
// when an AuthenticationError is thrown in a resolver
case "UNAUTHENTICATED":
// Modify the operation context with a new token
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: getNewToken(),
},
});
// Retry the request, returning the new observable
return forward(operation);
}
}
}
// To retry on network errors, we recommend the RetryLink
// instead of the onError link. This just logs the error.
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
});
My question is in regards to the getNewToken(), as no code was provided for this function, I want to know (assuming this is another request to the backend and I am not sure how it could not be), if you are able to and or supposed to use query/mutation in graphql or make the request through axios for example.
One problem, if it can/should be a graphql query or mutation, is to get the new token, the onError code is defined in the same file as the ApolloClient as ApolloClient needs access to onError, thus when trying to implement this as retrieving a new token through a graphql mutation I got the following error:
React Hook "useApolloClient" is called in function "refresh" that is
neither a React function component nor a custom React Hook function.
After trying to useQuery/useMutation hook and realizing I cannot outside of a react component and at the top level I found this post whose answers suggested you can use useApolloClient.mutate instead but I still ran into issues. My code was (and tried multiple iterations of this same code like useApolloClient() outside of the function and inside etc.):
const refresh = () => {
const client = useApolloClient();
const refreshFunc = () => {
client
.mutate({ mutation: GET_NEW_TOKEN })
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
};
refreshFunc();
};
I could capitalize Refresh but this still would not work and would break the rules of hooks.
And to clarify all the above would do is I would replace the console.logs with setting session storage to the retrieved new token and then re trying the original request with onError.
Now in another post I found when looking into this, the users getNewToken request was a rest request using axios:
const getNewToken = async () => {
try {
const { data } = await axios.post(
"https://xxx/api/v2/refresh",
{ token: localStorage.getItem("refreshToken") }
);
localStorage.setItem("refreshToken", data.refresh_token);
return data.access_token;
} catch (error) {
console.log(error);
}
};
Now from my understanding, if I wanted to implement it this way I would have to change my backend to include express as I am only using apolloserver. Now I could definitely be wrong about that as my backend knowledge is quite limited and would love to be corrected their.
So my question is, what is the best way to do this, whether natively using graphql queries/mutations (if possible), doing it with axios, or maybe their is another best practice for this seemingly common task I am unaware of.
I know that there is a very similar question like this one on StackOverflow, but i do not understand what the answer means, and because of that i am asking this question.
here's my code
const tokens = JSON.parse(fs.readFileSync("./tokens.json"));
const { accessToken, accessSecret, oauth_verifier } = tokens;
const client = new TwitterApi({
appKey: process.env.API_KEY,
appSecret: process.env.API_KEY_SECRET,
accessToken: accessToken,
accessSecret: accessSecret
});
const {client: Bot} = await client.login(oauth_verifier);
running this throws a 401 error with data saying Request token missing: ''.
i believe the problem lies in the oauth_verifier, as the code runs fine, and i have checked all my other credentials. I can also run a console.log() without running into errors if the last line in my code block above is commented.
The secret for getting this to work for me was not using .login().
Just instantiate the client using the details you got from the OAuth 1.0 auth flow. No need for .login()
I'm sending JWT tokens accross requests for authorization, however I can't seem to get the token decode each time. It works with one method but not the other. The first snippet gives a "decoded" token result from the server side, however the second one doesn't.
public async getAllUsers(req: Request, res: Response) {
try {
const payload = req["decoded"]; // gives the token decoded
if (payload) {
let users: ILoginResult = await UserData.getAllUsers(payload);
res.status(users.status).send(users.result);
}
} catch (e) {
res.status(500).send({ error: e.toString() });
}
}
public async getAccountDetails(req: Request, res: Response) {
try {
const user = req["decoded"]; // always undefined
let details: IDetails = await AccountData.getAccountDetails(name);
res.status(200).send(details);
} catch (e) {
let err = e.toString();
res.status(500).send({ error: err });
}
}
The request from postman are included a bearer token which is provided at login and used throughout other parts of the app. Not sure why it works in the one but not the other. Would really appreciate if someone could better explain what's going on here and/or provide tips, advice, suggestions.
edit - adding request details
get request to: http://localhost:5000/api/v1/account
with a token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE1Nzc5OTUwMjUsImV4cCI6MTU3ODE2NzgyNSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdCJ9.--msLba1VPs4Nv_B9YL6fk2DFHkQCgiVvDJFPt_UnDk
The decoded property was used in a tutorial I was following that seemed to be added from the server side but was poorly explained and I haven't found a good alternative/explanation. I don't think it has any middleware either. Very much open to alt methods.
Thanks to the suggestions from the comments I was able to find a missing piece in the route that creates the decoded property which is being used here. By adding the middleware to the router the request works as expected:
import express from "express";
import UserController from "../controllers/UserController";
import valid from "../utils/ValidateToken";
export default (router: express.Router) => {
router
.route("/users")
.post(UserController.addUser)
.get(valid.validateToken, UserController.getAllUsers);
router.route("/login").post(UserController.loginUser);
router.route("/account").get(valid.validateToken, UserController.getAccountDetails);
};
The valid.validateToken was missing which is the bit that generates the decoded object from the JWT being passed. Moral of the story, always double check everything. Thanks to all who commented/answered!
I'm building a search for image program using flickr API and im stucked at a certain error.
"Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
async function (async)
getData # index.js:19"
I can't get any data from the API. Can someone please explain why I get this error and how to fix it?
Here is JavaScript code
const api_key = "123456789ABCDEFGH";
let quantity = "5";
const userSearch = document.getElementById("search-field"); // input search
async function getData() {
const URL = `https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${api_key}&per_page=${quantity}&tags=${encodeURIComponent(
userSearch.value
)}`;
let response = await fetch(URL, { method: "GET" });
let data = await response.json();
return await data; // HERE is data error.
Add format=json param to your url. By default this endpoint returns results in xml format
Does nnot work, I had it before and removed just to try if it worked better without. Now when i added again, same problem..
If you mean like this:
const URL = `https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${api_key}&per_page=${quantity}&tags=${encodeURIComponent(
userSearch.value
)}&format=json`;
I solved it and will explain here if someone else need's it.
Also add this: &nojsoncallback=1`
const URL = `https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${api_key}&per_page=${quantity}&tags=${encodeURIComponent(
userSearch.value
)}&format=json&nojsoncallback=1`;
I am trying to use the GitHub Javascript API but am unable to authenticate using my API key. The API Docs say I can use:
{
username: 'my-username',
password: 'my-password'
// , token: 'or an optional oAuth token'
}
But I'd like to use my API Key instead, much like I can do with curl from the command line. (for example)
curl --user "$user:$api_key" --include --request DELETE "https://api.github.com/repos/$user/$repo/labels/enhancement"
I've tried using my API Key as the token but that doesn't work.
Is use of the API Key to access GitHub via the Github API wrapper not supported? That would be weird.
Okay so it turns out what I was calling my API Key is the same thing as the personal access token and I was just being confused because
import GitHub from 'github-api'
const gh = new GitHub({
token: 'MY-PERSONAL-ACCESS-TOKEN-OBTAINED-FROM-github.com/settings/tokens' // real token redacted obviously
})
const me = gh.getUser()
console.log('me', me)
was spitting out
me User {
__apiBase: 'https://api.github.com',
__auth:
{ token: '970818535b841883ff2735fe127d289032970389',
username: undefined,
password: undefined },
__AcceptHeader: 'v3',
__authorizationHeader: 'token MY-PERSONAL-ACCESS-TOKEN-OBTAINED-FROM-github.com/settings/tokens',
__user: undefined }
and I was interpreting __user: undefined to mean that the authentication was not working.
However if I actually try then adding
me.listNotifications().then(
notifications => console.log('notifications', notifications),
err => console.log('error', err)
).catch(err => console.log('fatal', err))
tadah it works.
If I throw in a rubbish token new GitHub doesn't complain (because presumably it's not actually going off to GitHub to do the auth at that point as I first thought), but the .listNotifications() does get rejected with a 401 error.
So, that's resolved my confusion.