I'm trying to send my login with :
'submit form': function(event) {
event.preventDefault();
event.stopPropagation();
var loginRequest = {
username: event.target.loginUsername.value.toLowerCase(),
password: event.target.loginPassword.value,
};
var callback = function(response) {
Session.set('showLoading', false);
};
Session.set('showLoading', true);
Accounts.callLoginMethod({
methodArguments: [loginRequest],
userCallback: callback,
});
},
But I get an error and I can't figure out what is the thing that create this error :
Exception while invoking method 'login' Error: Match error: Unknown key in field username
...
Sanitized and reported to the client as: Match failed [400]
I founded some informations in the web but nothing that really helped me. I think it's generated when I call Accounts.callLoginMethod
My form looks like this:
<form>
<div class="row">
<div class="input-field col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<label for="loginUsername">Username</label>
<input id="loginUsername" type="text" class="form-control" disabled="{{showLoading}}" required>
<br>
<label for="loginPassword">Password</label>
<input id="loginPassword" type="password" class="form-control" disabled="{{showLoading}}" required>
</div>
</div>
<br>
{{#if showLoading}}
{{> loading}}
{{else}}
<div class="text-center">
<button type="submit" class="btn btn-primary">Login</button>
</div>
{{/if}}
</form>
Someone could help me or know what is creating this error ?
Here is my 2 cents. Accounts.callLoginMethod is technically not a documented API function and in theory could change in any future Meteor release. Since it's not documented, the errors that it returns are not well defined and could be confusing.
Since you are just doing password authentication, I would recommend you use Meteor.loginWithPassword(user, password, [callback]) instead. At least this way you have a set of API documentation to fallback on if you get errors such as this (it also returns more specific errors when something goes wrong).
Try switching and see if you still receive an error output. If so the error will be one of the below error messages and you can better debug to see what's going on.
“Unrecognized options for login request [400]” if user or password is undefined.
“Match failed [400]” if user isn’t an Object or String, or password isn’t a String.
“User not found [403]” if the email or username provided in user doesn’t belong to a registered user.
“Incorrect password [403]” if the password provided is incorrect.
“User has no password set [403]” if user doesn’t have a password.
If you encounter one of the above errors, then do console.log(username) and make sure it is a string or object with the value that you are expecting.
Related
I'm developing an app using Laravel as backend and Angular as frontend. To login and register I'm trying to use JWT but when I try to register using the register form I get the following error: "ERROR TypeError: Cannot read property 'name' of undefined".
register.component.html
<form #registerForm=ngForm (ngSubmit)="onSubmit()">
<div class="form-group row mx-auto">
<label for="inputName3" class="col-md-6 col-form-label">Name</label>
<div class="col-md-12">
<input type="text" name="name" class="form-control"
placeholder="Name" [(ngModel)]="form.name" required>
<div class="alert alert-danger mt-2" [hidden]="!error.name">
<i class="fa fa-times-circle"></i> {{error.name}}
</div>
</div>
</div>
...
</form>
register.component.js
export class RegisterComponent implements OnInit {
public form = {
name: null,
email: null,
password: null,
password_confirmation: null
};
constructor(private http: HttpClient) { }
onSubmit(){
return this.http.post('http://localhost/api/auth/register',
this.form).subscribe(
data => console.log(data),
error => this.handleError(error)
);
}
ngOnInit() {
}
}
In the template, your test [hidden]='!error.name' is not valid because the variable error is not defined in the controller (.ts).
You should define error property with type object in the component.
because Angular expects an object called error with name key.
If you wait error from the backend or you need a quick solution just put ? (question mark) after error word in HTML like: [hidden]='!error?.name'.
This will make Angular check for error variable before checking for name property.
I have a problem with a checkbox in a form
<form id="form" action="/findPkgInstalled" role="form" method = "POST">
<div class="input-group col-xs-4">
<input type="text" name="pkgSearch" placeholder="Ricerca applicazione non installate..">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
<h6><input type="checkbox" name="filterName" checked>Filtra per nome</h6>
</form>
while in Python I have:
#app.route('/findPkgInstalled', methods=['POST'])
def findPkgInstalled():
error = None
pkg = request.form['pkgSearch']
if not pkg:
flash(u'Operazione errata, impossibile ricercare stringa vuota','warning')
return redirect(url_for('listInstalled'))
else:
if request.form['filterName'] is 'on':
appFound = aptsearch(pkg,True)
return render_template('find-pkg-not-installed.html', appFound = appFound)
else:
appFound = aptsearch(pkg,False)
return render_template('find-pkg-not-installed.html', appFound = appFound)
return redirect(url_for('listInstalled'))
box = request.form['filterName']
but this does not work. The error reported is 400 Bad Request. How can I do? Can you help me, please?
This error means that you're trying to fetch an object from your post request using incorrect key. For example if you uncheck filterName checkbox - this will cause this error:
request.form['filterName']
My advises:
0) Always check your post body to know what keys you can use to retrieve values from this body.
1) Use
request.form.get('filterName')
instead of
request.form['filterName']
because .get() returns None is there is no such key instead of throwing an exception inside flask that leads to 400 error
2) Use
request.form.get('filterName') == 'on'
instead of
request.form['filterName'] is 'on'
because is returns True if two variables point to the same object in memory. I'm not sure if you already have 'on' object in process memory
How do I display a message on a div <div asp-validation-summary="All" class="text-danger"></div> when I am sending a message from the back-end?
[HttpPost]
public IActionResult Signup(Signup signup)
{
var result = DBGetCls.GetList("SELECT * FROM Usertable WHERE Email = '{0}' ", signup.Email);
if (result.Count > 0)
{
object notFound = new { message = "Email has been used!" };
return BadRequest(notFound);
}
So my form would look like this:
<div id="signup">
<form asp-action="Signup">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="field-wrap">
<label asp-for="FullName" class="control-label active highlight">Name :</label>
<input asp-for="FullName" class="form-control" />
</div>
.
.
In your frontend MVC controller, you can add errors to the model state. These will be rendered in the validation summary. So when the backend answers with BadRequest, add an error manually.
ModelState.AddModelError("PropertyNameInViewModelToBeHighlighted",
"Error message to be shown in validation summary");
Some teams also build custom infrastructure to wrap the backend calls, catch any errors, extract the error message, and add it to the ModelState automatically.
See also What is the ModelState?
I'm trying to load an array (with simple text) and trying to load it up on the template whenever it is called. How do I get the ID from that specific item to get the array that I stored in it?
HTML Template:
<template name="commentMarker">
<div id="viewMarker">
<h3 id="markerTitle">{{markerName}}</h3>
<h6 id="markerCategory">{{markerCategory}}</h6>
<br>
<fieldset>
<legend>Description</legend>
<p>{{markerDescription}}</p>
</fieldset>
<form id="commentForm">
<fieldset>
<legend>Comments</legend>
<input type="text" id="markerId" name="idForComment" value={{markerId}}>
<textarea rows="3" cols="19" name="comment" id="commentArea" placeholder="Insert your comment here..."></textarea>
{{#each comments}}
<p id="oneComment">{{this}}</p>
{{/each}}
</fieldset>
<input type="submit" value="Comment" class="commentButton">
<input type="submit" value="Close" class="exitButton">
</form>
</div>
</template>
JS:
Template.commentMarker.helpers({
comments(){
alert(template.find("#markerId").value);
if(commentArray.length===0) return;
else return commentArray;
}});
This is where I insert the comment into the collection's item and it's working fine
Template.commentMarker.events({
'click .commentButton': function(e, template){
e.preventDefault();
var id = template.find("#markerId").value;
var comment = template.find("#commentArea").value;
Points.update(id, { $push: { comments: comment }});
commentArray = Points.findOne(id).comments;
template.find("#commentArea").value = ' ';
}
I tried with commentArray as a global variable which still is. But I'm at loss how I can get the Id from that specific item, I even put it's Id (with hidden display) in the form to actually be able to insert the comment. But it doesn't help me with showing the comments because I cannot seem to get to this field in the Template.helpers ...
Not entirely sure what you are trying to do. It's almost like as if you are displaying the comments right after you updated in to the collection. It looks like you are doing this entirely on local and not a online collection.
However, storing it as a session would work...or reactive var. Might not be the best solution tho. Basically replace commentArray = Points.findOne(id).comments; with:
Session.set('comments', Points.findOne(id).comments)
Then to get it out in helpers:
let commentArray = Session.get('comments')
It's not safe to use it all the time tho for sensitive data. Also try catch the findOne(id).comments because it does produce errors if it happen to not find it.
NOTE: If you are going to use Meteor.Methods, you cannot use Session. You have to return the id and find it in your helpers.
So I'm trying to create a Rails API with devise. My client side works well with GET, but I can't do POST type of calls. If I try to create a user I keep getting the following devise html form as response.
<h2>Sign up</h2>
<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="RGZxLuXcOCbxKVdpFc/wSAKEp3wcxqpfnvmv0nstEcOppPyViWcmdu+dPt84XQeSkCmwRg0REZN+vTdX1j+MOQ==" />
<div id="error_explanation">
<h2>2 errors prohibited this user from being saved:</h2>
<ul><li>Email can't be blank</li><li>Password can't be blank</li></ul>
</div>
<div class="field">
<div class="field_with_errors"><label for="user_email">Email</label></div><br />
<div class="field_with_errors"><input autofocus="autofocus" type="email" name="user[email]" id="user_email" /></div>
</div>
<div class="field">
<div class="field_with_errors"><label for="user_password">Password</label></div>
<em>(4 characters minimum)</em>
<br />
<div class="field_with_errors"><input autocomplete="off" type="password" name="user[password]" id="user_password" /></div>
</div>
<div class="field">
<label for="user_password_confirmation">Password confirmation</label><br />
<input autocomplete="off" type="password" name="user[password_confirmation]" id="user_password_confirmation" />
</div>
<div class="actions">
<input type="submit" name="commit" value="Sign up" />
</div>
</form>
Log in<br />
Didn't receive confirmation instructions?<br />
Interestingly, at first I would get a "Can't verify CSRF token authenticity" error, so I added beforeSend to my JSON call. This would than change my call to OPTIONS, even though it was specified as a POST.
My call:
$(document).on('page:change', function(){
$('body').on('submit', 'form.create_new_user', function(e){
e.preventDefault();
var user_data = $(this).serializeJSON();
$.ajax({
url: Host.address + '/users',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
type: 'post',
datatype:'json',
data: {info: {full_name: user_data.full_name,
email: user_data.email,
password: user_data.password,
password_confirmation: user_data.password_confirmation}}
}).done(function(response){
console.log(response)
if (response.success.success) {
logInGoToWithNotice(response, '/', 'Thank you for signig up');
} else{
alert("User wasn't created. Please try again.")
};
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
And API does this:
Started OPTIONS "/users" for ::1 at 2015-09-30 14:09:49 +0200
ActionController::RoutingError (uninitialized constant RegistrationsController):
...
If I now remove beforeSend, I'd get the form again, just that "Can't verify CSRF token authenticity" error wouldn't be there anymore, but instead I'd get successful POST, that still returns html form.
Started POST "/users" for ::1 at 2015-09-30 14:25:57 +0200
Processing by Devise::RegistrationsController#create as */*
Parameters: {"info"=>{"full_name"=>"User Admin", "email"=>"user.admin#email.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}
(0.1ms) BEGIN
(0.1ms) ROLLBACK
Rendered /Users/antonpot/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/devise-3.5.2/app/views/devise/shared/_links.html.erb (0.2ms)
Rendered /Users/antonpot/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/devise-3.5.2/app/views/devise/registrations/new.html.erb (3.5ms)
Completed 200 OK in 9ms (Views: 4.7ms | ActiveRecord: 0.2ms)
Now if I look into my Users Controller I can see I'm never even running my #create, as it never prints p "C"*99
class Users::RegistrationsController < Devise::RegistrationsController
def create
p "C"*99
user = User.new
user.full_name = user_params[:full_name]
user.email = user_params[:email].downcase
user.password = user_params[:password]
user.password_confirmation = user_params[:password_confirmation]
if user.save
render json: {success:{success: true, user_id: user.id, errorMessage: nil, errorNumber: 201}}
else
render json: {success:{success: false, errorMessage: user.errors.messages.to_s, errorNumber: 400}}
end
end
end
Why can't I call it? What do I need to do for this to work?
First
This issue because of cross-site-scripting problem. The client url is different than the api url. The HTTP method OPTIONS, is a pre-flight request that the browser makes to determine whether a cross-domain AJAX request should be allowed.
if cross-domain AJAX request is allowed the POST which is the actual request will be sent.
So you need to allow cross-domain AJAX request on your server.
Second
Make sure your routes.rb is set correctly.
You need to configure your devise and instruct him to use your customized registration_controller instead of default devise registration controller
adjust devise_for :users in your routes.rb to be something like the following:
devise_for :users, controllers: { registrations: "users/registrations"}
assuming that the customized registration class exist in the users folder