How to do HTTP GET within CodeIgniter? - php

Let's say I have a table called user
I want to make a HTTP call roughly like this
http://my.awesome.server/dev_api/index.php/login/get_user.php?user=steven&password=12345
Which checks the database if there's a user 'steve' with the password '12345'. These are my codes.
controller
<?php
if(!defined("BASEPATH")) exit("No direct script access allowed");
class login extends CI_Controller
{
public function index()
{
$this->load->model("login_model");
$data["users"]=$this->login_model->get_user();
$this->load->view("login_view", $data);
}
}
model
class Login_model extends CI_Model {
function get_user(){
// get username, like $_GET['user']
$user = $this->input->get('user');
// get the password and MD5-ed it, like md5($_GET['password'])
$md5_pass = md5($this->get('password'));
// the where condition
$this->db->where(array('userName' => $user, 'password' => $md5_pass));
// ok, now let's query the db
$q = $this->db->get('user');
if($q->num_rows() > 0){
foreach ($q->result() as $row){
$data[] = $row;
}
}
return $data;
}
}
?>
view
<?php
if (!empty($users)){
foreach ($users as $u){
echo $u->userId .' '. $u->userName.' '.$u->password.' ';
}
}
?>
Then I opened this on browser:
http://my.awesome.server/dev_api/index.php/login/. The result is
How to properly make a HTTP call, then?

The method in your model is name as get_user() while you call it as login_model->get()
More over you should use POST instead of GET for username and password.
Also use bcrypt or another hashing algorithm instead of MD5 it's more secure.
DO NOT USE MD5

You are trying to work against the framework you are using.
CodeIgniter abstract working with GET parameters by proposing you to use URL segments.
The URI scheme in CodeIgniter is as follow (see docs):
controller/method/params...
It is divided in segments:
the controller (mandatory)
the method (mandatory, but may be implied in case of index, see below)
the first param (optional)
the second param (optional)
... and so on
You want to use the method index() of the controller Login, it translates to
http://my.awesome.server/dev_api/index.php/login/index
Also, with mode_rewrite activated with htaccess, it could be simplified in
http://my.awesome.server/dev_api/login/index
Now, index() is a special method as it is the one called by default in a controller. Hence the final URL would be:
http://my.awesome.server/dev_api/login
Now, if you want to pass parameters to your function, CodeIgniter does this through subsequent segments.
But you need to declare them in the controller method.
class login extends CI_Controller
{
public function index($user = null, $password = null)
{
// Check for $user / $password emptiness
// ...
// Use $user / $password as needed
$data["users"]=$this->login_model->get_user($user , $password);
// use the results...
}
}
And now you could call with:
http://my.awesome.server/dev_api/login/index/steven/12345
Notice that I've put index in the URL? It's because when passing parameters, the method is mandatory.
That said, I will reiterate what other people have said:
Avoid passing login/password through GET. Prefer POST.
Use an encrypted connection (HTTPS)
Do NOT hash your password with md5 or even sha1. You need a strong algorithm. You also need to salt. Anyway, PHP got you covered with password_hash. Don't reinvent the wheel.
Good luck.

if you are passing data via url http://my.awesome.server/dev_api/index.php/login/get_user.php?user=steven&password=12345
You can retrieve it via URI segment
$user= $this->uri->segment(3);
$password= $this->uri->segment(4);
Sorce:
https://www.codeigniter.com/userguide3/libraries/uri.html
It is posible that this line $md5_pass = md5($this->get('password')); is setting the error if $this->get('password') is empty.

Related

Is using if else statement to load view based on parameters after controller and action part of url efficient or is there a better way of doing this

I can have the following urls
www.example.com/accounts/
www.example.com/accounts/signup
www.example.com/accounts/signup/validate
www.example.com/accounts/login
for each case, accounts becomes my controller, and index, signup, signup and login becomes my actions (or methods) respectively. I have to render different views based on what my actions are. Here is an example of what my code looks like
index
$url_segments = explode('/', $url);
$controller = !empty($url_segments[0]) ? $url_segments[0] : 'home';
array_shift($url_segments); // removes the controller name from array
$action = isset($url_segments[0]) && !empty($url_segments[0]) ? $url_segments[0] : 'index';
array_shift($url_segments); // removes the action name from array
$controller = ucfirst($controller);
$controller = new $controller($url_segments);
$controller->$action();
controller class
class Accounts{
private $url_segments;
public function __construct() {
$this->url_segments = $url_segments;
}
public function index() {
// index code here
}
public function login() {
// login code here
}
public function signup() {
if (!isset($this->url_segments[0])) {
// url entered was: example.com/signup
} else if (isset($this->url_segments[0]) && $this->url_segments[0] == 'validate') {
// url entered was: example.com/signup/validate
}
}
}
from how my code appeared above, it can be seen that as parameters keep adding after the controller and action part of the url I'll need to keep using conditional statements to run the proper code as in the case of /signup/ and signup/validate. Is this method of using conditional statement to load view based on parameters efficient or is there a better way of doing this.
I would recommend you to make use of a routing system like Symfony Routing. There you could add a new Route for every url and redirect them to your specific controller.
Example Route:
$routes = new RouteCollection();
$routes->add('/accounts_signup', route('POST', "/accounts/signup", 'App\Controller\AccountController:signup'));
return $routes;
This route would call the signup method in the AccountController calss when www.example.com/accounts/signup get called with a post request.
I recommend you to use something like this. Even if this might be a bit complicated for the beginning, after reading (and understanding) the docs this will safe you a lot of time and it will make your code more readable as well.

How to redirect different page from same controller function in laravel 5.2

I want to redirect 2 different page from this controller function along with value.Here is my code. It works but both of time url become same.what shuld I do?
//in routes.php
Route::post('/','mycontroller#check');
// in controller.php
public function check(Request $request)
{
$c_email = $request->email;
$c_pass=$request->pass;
$c_type=$request->select;
$var=DB::select("SELECT * FROM reg where email = '$c_email' and Password = '$c_pass' and type = '$c_type'");
if ($var) {
return view('farmer')->with('user',$var);
// return redirect('farmer')->with('user',$var);
}
else {
$msg="Invalid login";
return view('index')->with('show',$msg);
}
}
If you want to actually redirect u can use the redirect() helper as statet in the official docs https://laravel.com/docs/5.3/redirects
You can also pass data
redirect('/my-route')->with(['user' => $var]);
The passed data can then be accesses through the session helper
$var = session('user')
HOWEVER, it seems like you have major issues in your code. Your password does not seem to be encrypted. Also there's no reason to use plain sql instead of eloquent here.
The route that is shown in the browser is defined in your
Route::post('/','mycontroller#check');
If you just return different views, the route does not change. You need to redirect to other views.
If you redirect to other routes you will ofcourse need to add / define them.
Route::get('/my-route', function() {}); // or post etc.

OO PHP | Properly Passing POST Paramaters

I am relatively new to OO PHP and I am trying to create a login class.
The issue I am having is that I want to pass the POST values username and password to my class but I cannot establish a decent way of doing so.
below is a snippet of my class
class PortalLogin{
private $username;
private $password;
function __construct(){
//I connect to DB here
}
function login($username, $password){
//error check the paramaters here
//then I can run the query
}
function __destruct(){
//I disconnect from DB here
}
}
Above is a breakdown of the class I am creating below is how i plan to execute it (my main issue at the moment).
$login = new PortalLogin();
if(isset($_POST['username'])){
if(isset($_POST['password'])){
$login->login($_POST[username],$_POST[password]);
} else {
//throw error
}
} else {
//throw error
}
I really do not like the construction of the code above it seems to messy to be doing so much outside of my class. how can I pass the POST information to the class and execute the checks there? I am worrying that if I pass the POST information to the class and one of the POSTS contains nothing it will error.
I think you got a problem with the syntax of post..
if(isset($_POST['username']) && isset($_POST['password'])){
$login->login($_POST['username'],$_POST['password']);
}
use AND.. so if both username and password exist then call the login function()
I’m not sure where OOP comes in to this, but if you were going the object-oriented route you would have a class that represents a request from which you could grab POST data from:
$username = $request->post('username');
$password = $request->post('password');
Your post() method could return a default value (null) if the variable didn’t exist in the POST data.
You could then have a class that checks your user based on these variables:
$auth = new AuthService($dbConnection);
if ($auth->checkCredentials($username, $password)) {
// Valid user
} else {
$error = $auth->getLastError();
}
I know I might be in the minority with suggesting this, but I favour static methods for things like this. PortalLogin represents an action rather than data
class PortalLogin
{
/**
* Attempt login
* #param string $username
* #param string $password
*/
public static function login ($username, $password)
{
// do your login stuff
}
}
Then to use you would do this:
if (isset($_POST['username']
&& !empty($_POST['username']
&& isset($_POST['password']
&& !empty($_POST['password']
) {
PortalLogin::login($_POST['username'], $_POST['password']);
}
Even better OO would be to have the username/password checking baked into the User class. (Maybe User::checkLoginCredentials($u, $p); // boolean yup/nope)
You can use error suppression, like this:
$login->login(#$_POST['username'], #$_POST['password']);
If one or both values are not present in the $_POST variable, there won't be an error when calling the method, so you can do the error handling inside your class method.
For more info, check:
http://php.net/manual/en/language.operators.errorcontrol.php
Edit:
Another option is to do this:
$login->login((isset($_POST['username']) ? $_POST['username'] : null), (isset($_POST['password']) ? $_POST['password'] : null));

codeiginter no direct access to functions

I'm having this problem about direct access to functions: for example I have this code:
controller users
function index(){
//this is my users index view, user can add,edit,delete cars
}
function details($id){
//a function where 1 car can be viewed in detail..
function add(){
//function to add car
}
Now if I go to address bar and type. localhost/myapp/users/detail it will go to the url and echo an error since $id is null. What I want is only the index is directly accessible if a user would type in the address bar. I don't want the users to go directly to myapp/users/add, etc..
CI Controller functions always must be able to handle user input (i.e. url segments), which means anyone can type in whatever they wish and make a request. You can't stop that. The best practice is to either:
Always provide default arguments
Use the URI class to get your parameters, or func_get_args()
Always validate the presence of and integrity of arguments passed to the controller, as you would with any other user input
Since it's much more common, accepted, and easier to read - just make sure to always provide defaults and validate them.
An example with your controller:
function index() {
//this is my users index view
//user can add,edit,delete cars
}
function details($id = NULL) {
if ( ! $id) {
// No ID present, maybe redirect without message
redirect('users');
}
$user = $this->user_model->get($id);
if ( ! $user) {
// ID present but no user found, redirect with error message
$this->session->set_flashdata('error_message', 'User not found');
redirect('users');
}
// We found a user, load view here etc.
}
function add() {
// Check for the presence of a $_POST value
// You could also use the Form_validation lib here
if ( ! $this->input->post('add_car')
{
$this->session->set_flashdata('error_message', 'Invalid request');
redirect('users');
}
// Try to add the car here and always redirect from here
}
The only other way is to make the method private or use CI's _underscore() naming as suggested (making it inaccessible from the url). You can still call the function in other methods if you wish, as in:
function index() {
if ($this->input->post('add_car')
{
// Call the private "_add" method
$this->_add();
}
// Load index view
}
So to make a long story short: You can't stop the requests from being made, you can only decide what to do when the request is invalid.
Add an underscore before the names of functions you want to hide:
function _details($id){
//a function where 1 car can be viewed in detail..
}
function add(){
//function to add car
}

Is there an easy way to get AuthComponent user data from a view in CakePHP?

According to the cakebook section on the Auth component, I can implement simple authentication by using the following Users controller:
class UsersController extends AppController {
var $name = 'Users';
var $components = array('Auth'); // Not necessary if declared in your app controller
/**
* The AuthComponent provides the needed functionality
* for login, so you can leave this function blank.
*/
function login() {
}
function logout() {
$this->redirect($this->Auth->logout());
}
}
I would like to be able to something like the following into my view:
<?php
$username = $auth->user('username');
echo "Welcome " . $username;
?>
Is there a simple way to do this, or do I need to overwrite the login function and store the username to the session?
Update
Alexander's answer is exactly what I wanted. However, I will add the following in case someone else gets confused like I did.
It took me a while to understand that if you change the model that Auth uses (for example, you might have a 'persons' table instead of 'users'), then you need to use something like:
$persondata = $session->read('Auth.Person');
Actually this information is easily available from the session. You use the session helper to grab it. I believe the correct syntax is :
$userdata = $session->read('Auth.User');
$username = $session->read('Auth.User.username');
EDIT:
For CakePHP 2.X and on the syntax is:
$userdata = $this->session->read('Auth.User');
$username = $this->session->read('Auth.User.username');
Check out AuthComponent-Methods in the CakePHP manual....
You can access an user info after a user has logged in from the session via $this->Auth->User(). So if you want the username, just use this in the controller.
$this->set('username', $this->Auth->User('username'));
You can now use $username in the view.
Add a method in your AppController
function beforeFilter() {
$ath = $this->Auth->user();
$this->set('userDetails', $ath['User']);
}
And then you can access it from your views and/or layouts via $userDetails
To access Auth vars in views just do it:
echo $session->read('Auth.User.id');

Categories