am following up This tutorial to learn the jwt cool stuff. but when am testing the first bit of the server API with POSTMAN only the id,password fields are the one being inserted in the database. When I try to login with POSTMAN I get
MethodNotAllowedHttpException in RouteCollection.php line 218: from the server preview
my routes
Route::post('api/register', 'TokenAuthController#register');
Route::post('api/authenticate', 'TokenAuthController#authenticate');
Route::get('api/authenticate/user', 'TokenAuthController#getAuthenticatedUser');
my controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;
class TokenAuthController extends Controller
{
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
public function getAuthenticatedUser()
{
try {
if (!$user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return response()->json(compact('user'));
}
public function register(Request $request)
{
$newuser = $request->all();
$password = Hash::make($request->input('password'));
$newuser['password'] = $password;
return User::create($newuser);
}
}
I don't know where am messing out this code.
Related
I am trying to filter my http request by using middleware.
I want to check if the "friends_id" that i am getting from http request and "my_id" that I am passing in through Auth already don't exists in the same row, If they do I wanna redirect to home page and if they don't I wanna execute the normal request which will eventually insert the data that I am checking for
The error is "Trying to get property 'friends_id' of non-object "
Here's my "Friends" middleware:-
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class Friends
{
public function handle($request, Closure $next)
{ $auth = Auth()->user()->id;
$dost = $request->friends_id;
$ip = DB::table('friends')
->where('my_id', '=', $auth)
->where('friends_id', '=', $dost)
->get();
if($ip->friends_id != $dost){
return $next($request);
}
return redirect('/home');
}
}
Here's my friends Table:-
public function up()
{
Schema::create('friends', function (Blueprint $table) {
$table->id();
$table->string('my_id');
$table->string('friends_id');
$table->string('name');
$table->timestamps();
});
}
This is my Route:-
Route::post('/f', 'FriendsController#store')->middleware('friends');
-ThankYou
Try this
your query will be wrong use where instead of whereColumn and when you get first record use only first() not get()
use DB;
$ip = DB::table('friends')
->select('my_id', 'friends_id')
->where([['my_id', '=', '$auth'],['friends_id', '=', '$dost']])
->first();
EDIT
public function handle($request, Closure $next)
{
$auth = Auth()->user()->id;
$dost = $request->friends_id;
$ip = DB::table('friends')
->select('my_id', 'friends_id')
->where([['my_id', '=', '$auth'],['friends_id', '=', '$dost']])
->first();
if($ip->friends_id == $dost){
return redirect('/home');
} else {
return $next($request);
}
}
The Solution is:-
Friends Middleware:-
public function handle($request, Closure $next)
{
if (auth()->check()) {
$ip = DB::table('friends')->where('my_id', '=', auth()->id())->where('friends_id', '=', $request->friends_id)->first();
if ($ip && $ip->friends_id == $request->friends_id) {
return redirect('/home');
}
}
return $next($request);
}
}
I have a validator that checks if a vat-number is correct. In order to do that it calls an external service. This external call slows the tests down and is unreliable, so I would like to mock it, but I don't understand how I could do it.
public function validationDefault(Validator $validator)
{
$validator->setProvider('vat', 'App\Model\Validation\VatValidation');
$validator->add('vat_no', 'isValidVatNo', [
'rule' => 'validVatNumber',
'provider' => 'vat',
]);
}
And this is the validation provider:
<?php
namespace App\Model\Validation;
use Cake\Core\Configure;
use Cake\Validation\Validation;
use VatNumberCheck\Utility\Model\VatNumberCheck;
class VatValidation extends Validation
{
public static function validVatNumber($check)
{
$vatNumberCheck = new VatNumberCheck();
try {
return $vatNumberCheck->check($check);
} catch (InternalErrorException $e) {
return false;
}
}
}
public function testValidationFail() {
$VatValidator = $this->getMockBuilder('Cake\Validation\Validator')
->setMethods(['validVatNumber'])
->getMock();
$VatValidator->expects($this->any())
->method('validVatNumber')
->will($this->returnValue(false));
$this->Users->getValidator()->setProvider('vat', $VatValidator);
$user = $this->Users->newEntity([
'vat_no' => 'asdf',
]);
$errors = $user->errors();
$this->assertArrayHasKey('vat_no', $errors);
}
I have a UsersController'S signup action which gathers validation error messages like
if($user->errors()) {
$error_msg = [];
foreach( $user->errors() as $errors) {
if(is_array($errors)){
foreach($errors as $error) {
$error_msg[] = $error;
}
} else {
$error_msg[] = $errors;
}
}
if(!empty($error_msg)){
$this->Flash->error(__(implode("\n \r", $error_msg)) );
}
}
This kind of error messages I want to use in all controllers. This means I have to repeat the same code in all controllers? Or is there a way to write a central function without passing specific entity?
If you want to get model validation in string you can create a component which can be accessed from the controller
Create a component UtilsComponent.php under src/Controller/Component
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
class UtilsComponent extends Component
{
public function validationError($validationError)
{
$errorMsg = '';
if ($validationError) {
foreach ($validationError as $errorOn => $error) {
$errorMsg .= strtoupper($errorOn) . ': ' . implode(', ', $error) . "\n";
}
} else {
$errorMsg = 'Error Occurred! Try again';
}
return $errorMsg;
}
}
After that you can use this function anywhere in the controller like this
if ($this->Users->save($user)) {
// Do what you want
} else {
$this->Flash->error(__($this->Utils->validationError($user->errors())));
}
Hope this will help
Whenever I call this function, I get the user_id correctly but the password isnt checked...
Model:
<?php
class Prometheus_model extends CI_Model {
var $tables = array(
'bots' => 'bots',
'users' => 'users'
);
function __construct() {
parent::__construct();
}
public function tablename($table = NULL) {
if(! isset($table)) return FALSE;
return $this->tables[$table];
}
public function get($table, $where = array(), $order = NULL) {
$this->db->where($where);
if(isset($order)) {
$this->db->order_by($order);
}
$q = $this->db->get_where($this->tablename($table),$where);
$result = $q->result_array();
// You should use $q->num_rows() to detect the number of returned rows
if($q->num_rows()) {
return $result[0];
}
return $result;
}
public function update($table, $where = array(), $data) {
$this->db->update($this->tablename($table),$data,$where);
return $this->db->affected_rows();
}
public function insert($table, $data) {
$this->db->insert($this->tablename($table),$data);
return $this->db->insert_id();
}
public function delete($table, $where = array()) {
$this->db->delete($this->tablename($table),$where);
return $this->db->affected_rows();
}
public function explicit($query) {
$q = $this->db->query($query);
if(is_object($q)) {
return $q->result_array();
} else {
return $q;
}
}
public function num_rows($table, $where = NULL) {
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
public function get_bot_data_by_hw_id($bot_hw_id) {
$q = $this->get('bots', array('bot_hw_id' => $bot_hw_id));
return $q;
}
public function check_user_data($user_incredials, $user_password) {
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1){
$q = $this->get('users', array('user_name' => $this->security->xss_clean($user_incredials)));
return $q['user_id'];
}
return FALSE;
}
}
?>
My function-calling at the controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login extends CI_Controller {
public function index(){
if($this->input->post('user_login')){
var_dump($this->prometheus_model->check_user_data($this->input->post('user_incredials'), $this->input->post('user_password')));
}
$this->load->view('login_index');
}
}
How can i fixx this ?
In your check_user_data() method you are using
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1)
I think (logically) following code
$this->encrypt->decode($user_password)
should be
$this->encrypt->encode($user_password)
because, you are calling num_rows() method and it is
public function num_rows($table, $where = NULL)
{
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
which is actually querying the data base something like, for example,
select * from USERS where user_name = 'heera' and password = decode('abcde12345')
In this case, the password you are trying to match is need to be encrypted using encode (not decode) method, because the user has given you a non-encrypted (plain) password and the password saved in the database is already encrypted, so encode the plain password using encode method before you query the database to match with already encoded passwords.
Good day! I am now migrating my codes from 1.3 to 2.0 of CakePHP. And I just want to ask, how can I do this code (from 1.3) to 2.0? Here is the code:
function register() {
if(!empty($this->data)) {
// unset unrequired validation rules
unset($this->User->validate['username']['check_user']);
// validate & save data
if($this->User->save($this->data)) {
$this->data['User']['Password'] = md5($this->data['User']['Password']);
$this->User->save($this->data);
// set Flash & redirect
$this->Session->setFlash('You have successfully registered.','default',array('class'=>'flash_good'));
$this->redirect(array('action'=>'login'));
}
else{
//$this->Session->setFlash(__('The user could not be saved.' , true));
//$this->redirect(array('action' => 'register'));
}
}
}
and here is my attempt code that I tried to resolve:
public function register() {
if($this->request->is('post')) {
//unset($this->User->validate['username']['check_user']);
// validate & save data
//$this->data['User']['Password'] = md5($this->data['User']['Password']);
$this->request->data('User.Password', $this->request->data('User.Password'));
// $this->User->save($this->data);
// set Flash & redirect
if($this->User->save($this->request->data)) {
$this->Session->setFlash('You have successfully registered.','default',array('class'=>'flash_good'));
$this->redirect(array('action'=>'login'));
}
else{
//$this->Session->setFlash(__('The user could not be saved.' , true));
//$this->redirect(array('action' => 'register'));
}
}
}
This code is for the login, made in 1.3
function login() {
//echo $_SESSION['User']['auth'];
if(!isset($_SESSION['User']['id'])){
if(!empty($this->data)) {
if(($user = $this->User->validateLogin($this->data['User'])) == true)
{
//print_r(md5($this->data['User']['password']));
$user = $this->User->find('first',array('conditions'=>array('Username'=>$this->data['User']['Username'],'Password'=>md5($this->data['User']['Password']))));
//print_r ($user);
if(!empty($user)){
$_SESSION['User']['id'] = $user['User']['id'];
$_SESSION['User']['name'] = $user['User']['Name'];
$_SESSION['User']['auth'] = $user['User']['auth'];
$this->redirect(array('controller'=>'ads','action'=>'index'));
}else{
$this->Session->setFlash('Username/Password not match');
$this->redirect(array('action'=>'login'));
}
}
}
}
else{
$this->Session->setFlash('Login First.');
$this->redirect(array('controller'=>'ads','action'=>'index'));
}
}
and here is my code in 2.0 and still it is not working also.
public function login() {
if(!($this->Session->read('user_id'))){
if($this->request->is('post')) {
//$user = $this->User->find('first',array('conditions'=>array('Username'=>$this->data['User']['Username'],'Password'=>md5($this->data['User']['Password']))));
if(!empty($user)){
$this->Session->write('user_id',$user['User']['id']);
$this->Session->write('name',$user['User']['Name']);
//$this->Session->write('name',$user['User']['Name']);
$this->redirect(array('controller'=>'ads','action'=>'index'));
}else{
$this->Session->setFlash('Username/Password not match');
$this->redirect(array('action'=>'login'));
}
}
}else{
$this->redirect(array('controller'=>'ads','action'=>'index'));
}
}//end login
I hope that someone respond to my question. Thanks in advance.
I would first try running the migration on your existing code and you might be surprised. here is the link to the upgrade shell:
http://book.cakephp.org/2.0/en/console-and-shells/upgrade-shell.html#upgrade-shell
Try that first.