apollo client query with params - Vue - vue.js

Apollo-client's query:
apolloClient
.query({
query: authQuery,
variables: {
login: payload.login,
password: payload.password,
},
})
.then((res) => console.log(res)
Contents of authQuery (it's inside a file.gql):
query auth {
data
}
i always get the following response:
{
data: null
loading: false
networkStatus: 7
stale: true
}
Though in graphiQL i am getting correct response:
Query in a GraphiQL
{
auth(login:"root#admin", password:"1234")
}
And response:
{
"data": {
"auth": "eyJhbGciOi8"
}
}
I suspect my file.gql is the culprit? Or variables inside query not being read?

I had to wrap my query this way:
query Auth($login: String!, $password: String!) {
auth (login: $login, password: $password)
}
When you're using params with your Query, you always have to wrap it this way.

Related

Nuxt Auth login - working on localhost, 301 and 405 on server

My problem is, that login/logout works perfectly on my localhost, but as soon as I deploy it on a server I got 301 and 405 errors, with the "The GET method is not supported for this route. Supported methods: POST" message and I cant figure it out why is that.
My nuxt.config.js:
},
auth: {
strategies: {
local: {
user: {
property: 'data'
},
token: {
maxAge: 86400,
global: true
},
endpoints: {
login: { url: '/api/auth/login/', method: 'post' },
logout: { url: '/api/auth/logout/', method: 'post' },
user: { url: '/api/auth/user/', method: 'get' }
}
},
}
},
build: {
My login method:
async login() {
this.errors = {};
try {
await this.$auth.loginWith('local', { data: this.loginForm });
...
} catch (error) {
if (error.response.status === 401) {
this.inactive = error.response.data.message;
}
this.errors = error?.response?.data?.errors;
}
},
My Laravel api.php:
Route::group(['prefix' => 'auth'], function () {
Route::post('login/', [AuthController::class, 'login']);
Route::post('register', [AuthController::class, 'register']);
Route::post('set-password', [AuthController::class, 'setPassword']);
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::get('user/', [AuthController::class, 'user']);
Route::post('logout/', [AuthController::class, 'logout']);
Route::post('password-reset', [AuthController::class, 'passwordReset']);
});
});
And i will attach my network tab from my browser (first is on localhost/working, second one is on a server/not working):
I don't know what I'm messing up but after several days of debugging I'm hopeless. I've emptied every possible caches on the backend side so I'm thinking thats not the problem. But hopefully somebody else will be much more clever than me and can tell me what's going on.

KeystoneJS login via GraphQL mutation

I am trying to login to a Keystone 5 GraphQL API. I have setup the app so that I can login via the Admin Console, but I want to login from a Svelte application.
I keep finding references to the code below (I am new to GraphQL) but don't know how to use it.
mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}
If I post that query "as is" I get an authentication error, so I must be hitting the correct endpoint.
If I change the code to include my username and password
mutation signin("myusername", "mypassword") {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}
I get a bad request error.
Can anyone tell me how I send username/password credentials correctly in order to log in.
The full code I am sending is this
import { onMount } from 'svelte';
let users = [];
onMount(() => {
fetch("http://localhost:4000/admin/api", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}`
})
}).then(res => res.json())
.then(data => {
console.log(data)
})
})
Here is the response I get
{"errors":[{"message":"[passwordAuth:failure] Authentication failed","locations":[{"line":2,"column":3}],"path":["authenticate"],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["Error: [passwordAuth:failure] Authentication failed"," at ListAuthProvider._authenticateMutation (/Users/simon/development/projects/keystone/meetings-api/node_modules/#keystonejs/keystone/lib/providers/listAuth.js:250:13)"]}},"uid":"ckwqtreql0016z9sl2s81af6w","name":"GraphQLError"}],"data":{"authenticate":null},"extensions":{"tracing":{"version":1,"startTime":"2021-12-03T20:13:44.762Z","endTime":"2021-12-03T20:13:44.926Z","duration":164684813,"execution":{"resolvers":[{"path":["authenticate"],"parentType":"Mutation","fieldName":"authenticateUserWithPassword","returnType":"authenticateUserOutput","startOffset":2469132,"duration":159500839}]}}}}
I found the answer eventually.
You have to provide an extra object in your body called variables
variables: {
var1: "value1",
var2: "value2"
}
Those variables will then replace the placehodlers in the query like $var1 or $var2
Here is the full fetch code that works.
fetch("http://localhost:4000/admin/api", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}`,
variables: {
identity: "myusername",
secret: "mypassword"
}
})
}).then(res => res.json())
.then(data => {
console.log(data)
})
It's a shame that KeystoneJS don't provide any full code examples in their documentation. It would have saved me hours of searching.
As you say #PrestonDocks, if your query defines variables, you need to supply the variable values in a separate top level object. For the benefit of others I'll link to the GraphQL docs on this.
The alternative is to not use variables and to in-line your values in the query itself, like this:
mutation signin {
authenticate: authenticateUserWithPassword(
email: "me#example.com",
password: "Reindeer Flotilla"
) {
item {
id
}
}
}
But variables usually end up being neater.

GraphQl generate Syntax Error: Expected $, found {]

laugh =async()=> {
let mutation = gql`
mutation SignUp({$Email: String!
$Password: String!
}){
SignUp(data: {
Email: "tael32#gmil.com"
Password: "12345678"
}) {
User {
_id
Name
Rating
Photo
Badge
Email
}
Token
}}
`;
try {
let data = await client.mutate({mutation});
console.log('TCL: login -> data', data);
} catch (error) {
console.log('Majid', error);
}
}
when i call this function it generate error in code while it run correctly in post
mutation {
SignUp(data: {
Email: "chetanvirani#gmail.com"
Password: "12345678"
Name: "Chetan"
}) {
User {
_id
Name
Rating
Photo
Password
Badge
Email
}
Token
}
}
here the code which run in postman but not in a code,i don't know what was was the error in my code
Curly braces specify a selection set. There's no reason to wrap your variable definitions in curly braces:
mutation SignUp($Email: String!, $Password: String!) {
...
}

How do I format an array passed to params of an axios get to this specific format: [0].mfr=mfr0&[0].mpn=mpn0&[1].mfr=mfr1&[1].mpn=mpn1

I'm making a axios get call to a web api that is looking to have the query string parameters in this specific format which seems uncommon: [0].mfr=mfr0&[0].mpn=mpn0&[1].mfr=mfr1&[1].mpn=mpn1
I've been trying to use the Qs library to stringify the params in the paramsSerializer option.
parts = [{ mfr: "mfr0", mpn: "mpn0" }, { mfr: "mfr1", mpn: "mpn1" }]
findParts(parts, token) {
return axios
.request({
url: "https://<serveraddress>/api/v1/parts/findparts",
method: "get",
params: parts,
headers: {
Authorization: "Bearer " + token,
"Content-Type": "text/plain"
}
})
.catch(error => {
console.log(error);
Vue.notify({
type: "error",
title: "Unable to find parts",
text: "Unable to find parts"
});
});
}
result
0={"mfr":"mfr0","mpn":"mpn0"}&1={"mfr":"mfr1","mpn":"mp1"}
paramsSerializer: function(params) {
return qs.stringify(params);
},
or
paramsSerializer: function(params) {
return qs.stringify(params, { arrayFormat: "brackets" });
},
or
paramsSerializer: function(params) {
return qs.stringify(params, { arrayFormat: "indices" });
},
result
0[mfr]=mfr0&0[mpn]=mpn0[mfr]=mfr1&1[mpn]=mpn1
paramsSerializer: function(params) {
return qs.stringify(params, { allowDots: true });
},
result
0.mfr=mf0&0.mpn=mpn0&1.mfr=mfr1&1.mpn=mpn1
I can create a custom paramsSerializer but I was wonder if there a way to manipulate qs or the passed parts array to get the correct query string results without having to manually create the query string and url encode the values?

Catch error server response with #nuxtjs/auth

I'm trying to catch the error response for #nuxtjs/auth but it doesn't seem to return anything but undefined.
It refuses to login if I include the user so I want to know why it's returning undefined.
CONFIG:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: 'http://127.0.0.1:80/api/login',
method: 'post',
propertyName: 'token'
},
logout: false,
user: {
url: 'http://127.0.0.1:80/api/me',
method: 'get',
propertyName: undefined
}
},
tokenRequired: true,
tokenType: 'bearer',
}
},
plugins: [
'#/plugins/auth.js'
]
},
PLUGIN:
export default function ({ app }) {
app.$auth.onError((error, name, endpoint) => {
console.error(name, error)
});
}
VIEW FUNCTION:
- both handleSuccess and handleFailure returns undefined.
login() {
this.toggleProcessing(0);
let payload = {
username: 'admin',
password: 'admin123'
}
let handleSuccess = response => {
console.log(response);
this.toggleProcessing(0);
}
let handleFailure = error => {
console.log(error);
this.toggleProcessing(0);
}
this.$auth.loginWith('local', { data: payload }).then(handleSuccess).catch(handleFailure);
},
You can use e.response
async login() {
try {
const login = {
username: this.username,
password: this.password
}
let response = await this.$auth.loginWith('local', { data: login })
console.log('response', response)
} catch (e) {
console.log('Error Response', e.response)
}
}
I fell into the same problem and after spending some time i found out a very good way to catch the response. The solution is to use the axios interceptor. Just replace your plugin file code with the following
export default function ({$axios, $auth}){
$axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
}
I'm not sure initially what might be wrong here because I can't see the complete nuxt.config.js and your full component but here are a few things to check:
#nuxtjs/axios is installed
Both axios and auth modules are registered in the modules section of nuxt.config.js:
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth'
]
Also, ensure the middleware property for auth is set in the component/page component.
Ensure you're following the documentation on this page: https://auth.nuxtjs.org/getting-starterd/setup
Ive been using try -> this.$auth.loginWith to catch error server response with #nuxtjs/auth.
login() {
const data = { form };
try {
this.$auth
.loginWith("local", { data: data })
.then(api => {
// response
this.response.success = "Succes";
})
.catch(errors => {
this.response.error = "Wrong username/password";
});
} catch (e) {
this.response.error = e.message;
}
},
Specify the token field in the nuxt.config
strategies: {
local: {
endpoints: {
login: { // loginWith
url: "auth/login",
method: "post",
propertyName: "data.token" // token field
},
user: { // get user data
url: "auth/user",
method: "get",
propertyName: "data.user"
},
}
}
},
modules: ["#nuxtjs/axios", "#nuxtjs/auth"],