Change hotspot password with PHP API

Hi,

I am working on a simple PHP script to change password of a hotspot user.
A simple example would be great.

Right now i am doing this with a BASH script from a Linux Server. I get a STD Timeout error almost all the time while changing password, i dont understand why i get this.
Also if someone can brief me about this STD Timeout error.

Looking forward for a positive reply.

it would be easier to help if you posted some code example of what you are doing

HI,

uptill now i have only made login system, and a simple html form with required fields.
form has following fields

  1. userid
  2. old password
  3. new password
  4. confirm password.

i have made a function to check new password and confirm password. after that the password should go through the php.api syntax to mikrotik to change the password for the userid.

a simple example would be much more helpfull. I only want to know the correct sytax to be used with php.api to change password for hotspot user.

again, please post CLI command to do that =) and it will be easy to translate it into API command

Hi,

Thanks for th reply.

the CLI command is simple.
“ip hotspot user set User_Name password=New_Password”

i want this to do through the PHP API, a working example would be great.

Thanks in advance.

as far as I understand, in canonical form it’s

/ip hotspot user set [find name="User_Name"] password=New_Password

so, look at http://forum.mikrotik.com/t/api-acl-control/29390/1

Can you post your PHP that you have so far on this? Do you think it would be easier to do in PERL?

-Sincerely,
DesertAdmin

My code is like this and is not changing the password please help. I am able to connect and to pull up the array of information but I can n ot do a set /change for a password. any ideas?

I am trying to locate the username ilfeld and then change it to the following test password of yoyo. The username appears to be listed as id *5. What am I doing wrong? This is with the PHP API.

        $API->write('/ip/hotspot/user/getall');
	$API->write('=.proplist=name');
	$API->write('?name=ilfeld');
	$API->write('/ip/hotspot/user/set');
	$API->write('=.id=*5');	
	$API->write('=password=yoyo');

	$READ = $API->read(false);
	$ARRAY = $API->parse_response($READ);
	print_r($ARRAY);

Thanks in advance

-Sincerely,
DesertAdmin

You forgot to end the sentence.
Call $API->finish_sentence(); before trying to read anything.

…forget that comment, I have a modified version of the API :slight_smile:

With the “official” API you would have to write:

   $API->write('/ip/hotspot/user/getall',false);
   $API->write('=.proplist=name',false);
   $API->write('?name=ilfeld');
#you have to read out something at this point
   $API->write('/ip/hotspot/user/set',false);
   $API->write('=.id=*5',false);   
   $API->write('=password=yoyo');

Awesome that worked!!

Here is what my hotspot password page looks like. I have two files that I made but I also use the routeros_api.class.php (of course) on my secure https server.
Files:
hotspot.php
hspot1.php
routeros_api.class.php


Here is the code for my basic login page for the hotel managers to use: https://server.address.com/hman/hotspot.php

<html>
<body>
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form name="form1" method="post" action="hspot1.php">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td colspan="3"><strong>HotSpot Admin Login </strong></td>
</tr>
<tr>
<td width="78">Username</td>
<td width="6">:</td>
<td width="294"><input name="myusername" type="text" id="myusername"></td>
</tr>
<tr>
<td>Password</td>
<td>:</td>
<td><input name="mypassword" type="password" id="mypassword"></td>
</tr>

<tr>
<td width="78">Hotel Username</td>
<td width="6">:</td>
<td width="294"><strong>ilfeld</strong></td>
</tr>
<tr>
<td>New Password</td>
<td>:</td>
<td><input name="guestpassword" type="password" id="guestpassword"></td>
</tr>

<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="Login"></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
 <script language="JavaScript">
<!--
document.hotspot.myusername.focus();
//-->

</script>
</body>
</html>

My code calls hspot1.php Please change the IP address of the server and use a username and password that is only able to change hotspot usernames and passwords. For instance I made a login user that can only write as the username of manager with a simple to remember password. This will only allow that username to change the passwords. Do not forget to enable the API service port and set it to your address range accordingly. Or you can create a rule set that would allow only your IP address ranges. Once you have that setup find the username that you want always to change and get its ID if the hotspot user is the number 4 on the list that call your .id=*5 because it is counting the number 0.

<?php

require('routeros_api.class.php');

$API = new routeros_api();

$API->debug = false;
$myusername = $_POST["myusername"];
$mypassword = $_POST["mypassword"];
$guestpassword = $_POST["guestpassword"];
$cmmnd ="=password=";
$cmmnd .=$guestpassword;
$ipofsvr="111.111.111.111";

if ($API->connect($ipofsvr, $myusername, $mypassword)) {

	echo "Password Changed successfully!";

	$API->write('/ip/hotspot/user/getall',false);
	$API->write('=.proplist=name',false);
	$API->write('?name=ilfeld');
	$API->write('/ip/hotspot/user/set',false);
	$API->write('=.id=*5',false);
	$API->write($cmmnd);

	$READ = $API->read(false);
	$ARRAY = $API->parse_response($READ);
	
	$API->disconnect();

}
else 
{
  echo "Incorrect Username or Password! Please try again!";
  $API->disconnect();
} 
?>

If you all have any questions or comments please post it back. Thanks for everyones help.

-Sincerely,
DesertAdmin

Here is my newest modification to the page for our hotel managers to change their basic guest account password for their hotspot. All other customers who need greater then 128k will then purchase bandwidth from us.
hotelmanagerpage.JPG
I have this nicely secured on our https site that is only accessible on our networks.

Let me know what you think!

Thanks

-Sincerely,
DesertAdmin

Hi Everyone,I am trying to build a system similar to what is being discussed on this page,using some info on this page
I want hotspot users to change their passwords after they have logged in.
The login.html and status.html are from the default mikrotik hotspot folder

The sequence:
login.html (usual login page)>>>>>status.html (generated after successful login)>>>>changepass.php (forwaded from a link on status.html)>>>>>hspot1.php

but i am having difficulty after the hspot1.php is called,i only see the code being displayed on the web page and that is it.no password is changed!!!
i need help


NB
i have no experience in php,html,java..this is my first time..i have come this far courtesy of this forum and google.


here is the status page code


<html>
<head>
<title> hotspot > status</title>
<style type="text/css">
<!--
.style1 {
	color: #660000;
	font-weight: bold;
}
-->
</style>
$(if refresh-timeout)
<meta http-equiv="refresh" content="$(refresh-timeout-secs)">
$(endif)
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="-1">
<style type="text/css">
<!--
textarea,input,select {
	background-color: #FDFBFB;
	border: 1px #BBBBBB solid;
	padding: 2px;
	margin: 1px;
	font-size: 14px;
	color: #808080;
}

.tabula{
 
border-width: 1px; 
border-collapse: collapse; 
border-color: #c1c1c1; 
background-color: transparent;
font-family: verdana;
font-size: 11px;
}

body{ color: #737373; font-size: 12px; font-family: verdana; }

a, a:link, a:visited, a:active { color: #AAAAAA; text-decoration: none; font-size: 12px; }
a:hover { border-bottom: 1px dotted #c1c1c1; color: #AAAAAA; }
img {border: none;}
td { font-size: 12px; padding: 4px;}
.style2 {color: #660000}

-->
</style>
<script language="JavaScript">
<!--
$(if advert-pending == 'yes')
    var popup = '';
    function focusAdvert() {
	if (window.focus) popup.focus();
    }
    function openAdvert() {
	popup = open('$(link-advert)', 'hotspot_advert', '');
	setTimeout("focusAdvert()", 1000);
    }
$(endif)
    function openLogout() {
	if (window.name != 'hotspot_status') return true;
        open('$(link-logout)', 'hotspot_logout', 'toolbar=0,location=0,directories=0,status=0,menubars=0,resizable=1,width=280,height=250');
	window.close();
	return false;
    }
//-->
</script>
</head>
<body bottommargin="0" topmargin="0" leftmargin="0" rightmargin="0"
$(if advert-pending == 'yes')
	onLoad="openAdvert()"
$(endif)
>
<table width="100%" height="100%">

<tr>
<td align="center" valign="middle">
<form action="$(link-logout)" name="logout" onSubmit="return openLogout()">
<table border="1" class="tabula">
$(if login-by == 'trial')
	<br><div style="text-align: center;">Welcome trial user!</div><br>
$(elif login-by != 'mac')
	<br><div style="text-align: center;">Welcome $(username)!</div><br>
$(endif)
	<tr><td align="right">IP address:</td><td>$(ip)</td></tr>
	<tr><td align="right">bytes up/down:</td><td>$(bytes-in-nice) / $(bytes-out-nice)</td></tr>
$(if session-time-left)
	<tr><td align="right">connected / left:</td><td>$(uptime) / $(session-time-left)</td></tr>
$(else)

	<tr><td align="right">connected:</td><td>$(uptime)</td></tr>
$(endif)
$(if blocked == 'yes')
	<tr><td align="right">status:</td><td><div style="color: #FF8080">
<a href="$(link-advert)" target="hotspot_advert">advertisement</a> required</div></td>
$(elif refresh-timeout)
	<tr><td align="right">status refresh:</td><td>$(refresh-timeout)</td>
$(endif)
</table>
$(if login-by-mac != 'yes')
<br>
<!-- user manager link
<button onclick="document.location='http://$(hostname)/user?subs='">status</button>
<!-- end of user manager link -->
<input type="submit" value="log off">
<label>
/</label>
<p>$(endif)</p>
<p class="style1"><a href="changepass.php">CHANGE PASSWORD</a></p>
</form>


</td>
</table>
</body>
</html>

code for changepass.php


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form name="form1" method="post" action="hspot1.php">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td colspan="3"><strong>HotSpot User Password change</strong></td>
</tr>
<tr>
<td width="78">Username</td>
<td width="6">:</td>
<td width="294"><input name="myusername" type="text" id="myusername"></td>
</tr>
<tr>
<td>Old Password</td>
<td>:</td>
<td><input name="mypassword" type="password" id="mypassword"></td>
</tr>

<tr>
<td width="78">&nbsp;</td>
<td width="6">&nbsp;</td>
<td width="294">


</td>
</tr>
<tr>
<td>New Password</td>
<td>:</td>
<td><input name="newpassword" type="password" id="newpassword"></td>
</tr>

<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="submit"></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
<script language="JavaScript">
<!--
document.hotspot.myusername.focus();
//-->

</script>
</body>
</html>




then code for hotspot1.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>


<?php

require('routeros_api.class.php');

$API = new routeros_api();

$API->debug = false;
$myusername = $_POST["myusername"];
$mypassword = $_POST["mypassword"];
$newpassword= $_POST["newpassword"]
$cmmnd ="=password=";
$cmmnd .=$newpassword;
$ipofsvr="172.16.1.1";

if ($API->connect($ipofsvr, $myusername, $mypassword)) {

   echo "Password Changed successfully!";

   $API->write('/ip/hotspot/user/getall',false);
   $API->write('=.proplist=name',false);
   $API->write('?name=$myusername');
   $API->write('/ip/hotspot/user/set',false);
   $API->write('=name=$myusername',false);
   $API->write($cmmnd);

   $READ = $API->read(false);
   $ARRAY = $API->parse_response($READ);
   
   $API->disconnect();

}
else
{
  echo "Incorrect Username or Password! Please try again!";
  $API->disconnect();
}
?>


<body>
</body>
</html>

are you trying to put these pages on Router? If yes, then it will not work. You will have to place these pages on php capable http server, that RouterOS is not.

ok.thanks for that info,i have realised my mistake.

Now what i have done is to maintain the login.html and status.html on the router ,then i have created a link on status .html to change password which links to changepass.html which then redirects the user to changepass.php and hspot1.php on an external server running wampserver 2i
The router’s ip address is 172.16.1.1,user admin and no password


i have logged in to the system with a user named “admin” password “admin”,and i want to change password to test,when i run the code

hspot.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>


<?php

require('routeros_api.class.php');

$API = new routeros_api();

$API->debug = true;
$myusername = $_POST["myusername"];
$mypassword = $_POST["mypassword"];
$newpassword= $_POST["newpassword"];
$ipofsvr="172.16.1.1";

if ($API->connect($ipofsvr,'admin',"")) {


   $API->write('/ip/hotspot/user/getall',false);
   $API->write('/ip/hotspot/user/set/',false);
   $API->write('=.id='.$myusername,false);
   $API->write('=password='.$newpassword);

   $READ = $API->read(false);
   $ARRAY = $API->parse_response($READ);
   
   $API->disconnect();
   
   echo "Password Changed successfully!";

}
else
{
  echo "Incorrect Username or Password! Please try again!";
  $API->disconnect();
}
?>


<body>
</body>
</html>

i get this output with debugging on

Connection attempt #1 to 172.16.1.1:8728... <<< [6] /login >>> [5, 39] !done >>> [37, 1] =ret=42aa9f5618bbc947415e1a680ee3b2b7 <<< [6] /login <<< [11] =name=admin <<< [44] =response=00b9325a654b8954ac191945f299c4c093 >>> [5, 1] !done Connected... <<< [23] /ip/hotspot/user/getall <<< [21] /ip/hotspot/user/set/ <<< [10] =.id=admin <<< [14] =password=test >>> [3, 189] !re >>> [7, 181] =.id=*1 >>> [11, 169] =name=admin >>> [15, 153] =password=admin >>> [16, 136] =profile=default >>> [16, 119] =uptime=1h30m12s >>> [18, 100] =bytes-in=21293900 >>> [19, 80] =bytes-out=22015929 >>> [17, 62] =packets-in=26375 >>> [18, 43] =packets-out=21254 >>> [11, 31] =dynamic=no >>> [9, 21] =comment= >>> [12, 8] =disabled=no >>> [5, 1] !done Disconnected... Password Changed successfully!

but the password is not changed whatsoever.
i have api enabled to allow address range of 172.16.1.0/24



code for changepass.php


<?php
$username = $_POST['user'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form name="form1" method="post" action="hspot1.php">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td colspan="3"><strong>HotSpot User Password change</strong></td>
</tr>
<tr>


<td width="78">Username</td>
<td width="6">:</td>
<td width="294"><?php echo $username; ?><input name="myusername" type="hidden" id="myusername" value="<?php echo $username; ?>"></td>
</tr>
<tr>
<td>Old Password</td>
<td>:</td>
<td><input name="mypassword" type="password" id="mypassword" ></td>
</tr>

<tr>
<td width="78">&nbsp;</td>
<td width="6">&nbsp;</td>
<td width="294">


</td>
</tr>
<tr>
<td>New Password</td>
<td>:</td>
<td><input name="newpassword" type="password" id="newpassword"></td>
</tr>

<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="submit"></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
<script language="JavaScript">
<!--
document.hotspot.myusername.focus();
//-->

</script>
</body>
</html>

now i’m stuck,dont know wat to do

Well the API is meant to change a username at place “.id=*1” I do believe. So you may need to modify the .id value to the corresponding username. You may need to do a find to get the correct id position and +1 ( I may be incorrect.)

I think that is the whole problem. Of course this does appear that you are using a routerboard with the hotspot code on it.

-Sincerely,
DesertAdmin

ok.
so i want ahead and changed the line

$API->write('=.id='.$myusername,false);

to

$API->write('=.id=*1,false);

b’cos from the output i clearly see .id has a value of *1
it still behaved as if the password has been changed,but logging into the router shows otherwise.
i’m currently running v3.13 routeros
but i was suspecting maybe there is a bug so i upgraded to 3.22 and when i run the same code i get

Connection attempt #1 to 172.16.1.1:8728... <<< [6] /login >>> [5, 39] !done >>> [37, 1] =ret=3c459371715010e0476c6d91d2995876 <<< [6] /login <<< [11] =name=admin <<< [44] =response=00393c8c29e1e089dbbf83a720fc58bcc8 >>> [5, 1] !done Connected... <<< [23] /ip/hotspot/user/getall <<< [21] /ip/hotspot/user/set/ <<< [10] =.id=admin <<< [14] =password=test >>> [5, 35] !trap >>> [26, 8] =message=unknown parameter >>> [5, 1] !done Disconnected... Password Changed successfully!

what unknown parameter is it talking about?how can i identify it
i’m so confused now,but i never give up

back to your suggestion about the find,i came up with this code

<?php

require('routeros_api.class.php');

$API = new routeros_api();

$API->debug = true;
$myusername = $_POST["myusername"];
$mypassword = $_POST["mypassword"];
$newpassword= $_POST["newpassword"];
$ipofsvr="172.16.1.1";

if ($API->connect($ipofsvr,'admin',"")) {


   $API->write('/ip/hotspot/user/getall');
   $API->write('=.proplist=.id',false);
   $API->write('?name='.$myusername);
   
   $A = $API->read();
   $A = $A[0];
   
   echo "list  .id value" .$A;
   
   
   $READ = $API->read(false);
   $ARRAY = $API->parse_response($READ);
   
   $API->write('/ip/hotspot/user/set/',false);
   $API->write('=.id='.$A['.id'],false);
   $API->write('=password='.$newpassword);
   $API->read();

   
   
   $API->disconnect();
   
   echo "Password Changed successfully!";

}
else
{
  echo "Incorrect Username or Password! Please try again!";
  $API->disconnect();
}
?>

when i run i get this output

Connection attempt #1 to 172.16.1.1:8728... <<< [6] /login >>> [5, 39] !done >>> [37, 1] =ret=c8e0d23ebe4ba26d3143df7ad2ba87a4 <<< [6] /login <<< [11] =name=admin <<< [44] =response=00e6d723bf535a6070e54f046d0acd1f26 >>> [5, 1] !done Connected... <<< [23] /ip/hotspot/user/getall <<< [14] =.proplist=.id <<< [11] ?name=admin >>> [5, 223] !trap >>> [31, 191] =message=no such command prefix >>> [5, 184] !done >>> [3, 179] !re >>> [7, 171] =.id=*1 >>> [9, 161] =comment= >>> [11, 149] =name=admin >>> [15, 133] =password=admin >>> [16, 116] =profile=default >>> [16, 99] =uptime=06:34:31 >>> [18, 80] =bytes-in=67384966 >>> [19, 60] =bytes-out=22911619 >>> [17, 42] =packets-in=63280 >>> [18, 23] =packets-out=29152 >>> [14, 8] =dynamic=false >>> [5, 1] !done list .id valueArray
Notice: Undefined variable: _ in C:\wamp\www\hotspot\routeros_api.class.php on line 217

Notice: Undefined variable: _ in C:\wamp\www\hotspot\routeros_api.class.php on line 217

Notice: Undefined variable: _ in C:\wamp\www\hotspot\routeros_api.class.php on line 217

Notice: Undefined variable: _ in C:\wamp\www\hotspot\routeros_api.class.php on line 217

people i need help with these codes,like i said this is my 1st time with php and api

this is line 217 of the routeros_api.class.php,i

if ((!$this->connected && !$STATUS['unread_bytes']) || ($this->connected && $_ == '!done' && !$STATUS['unread_bytes']))

does any1 have an updated version of routeros_api.class.php cos anyway i twist my code now i seem to get a an error on the above line,and elsewhere

try:

/ip/hotspot/user/set

instead of:

/ip/hotspot/user/set**/**

remember API sentence contains of command and arguments:

/this/is/the/command
=these=arguments

output remains the same after using

/ip/hotspot/user/set

does not work

The .id number is the user in its sequential order listed in the hotspot username area. For instance I have the following under my:

[username@Plazahotelilfeld] /ip hotspot user> pri
Flags: X - disabled, D - dynamic

SERVER NAME ADDRESS PROFILE UPTIME

0 ilfeld guest 1w2d2h20m40s
1 admin default 22m15s
2 staff iphone 3m28s

Which would make the place +1 equal ‘=.id=*1’ for the username of ilfeld and ‘=.id=*2’ for the username of admin and so fourth.

Do you have the routeros_api.class.php in the same folder on the off site server?
If not you need to get it from the http://wiki.mikrotik.com/wiki/API_PHP_class

Let me know if that helped.

-Sincerely,
DesertAdmin

do not assume things.here is simple example:

[admin@test-B] /ip hotspot user> add name=one 
[admin@test-B] /ip hotspot user> add name=two 
[admin@test-B] /ip hotspot user> add name=three
[admin@test-B] /ip hotspot user> print 
Flags: X - disabled, D - dynamic 
 #   SERVER                   NAME              ADDRESS              PROFILE                     UPTIME      
 0                            one                                     default                        0s          
 1                            two                                     default                        0s          
 2                            three                                   default                        0s          
[admin@test-B] /ip hotspot user> :put [find]
*1;*2;*3
[admin@test-B] /ip hotspot user> add name=four 
[admin@test-B] /ip hotspot user> remove [find where name="two"]
[admin@test-B] /ip hotspot user> add name=two                  
[admin@test-B] /ip hotspot user> :put [find]                   
*1;*3;*4;*5

look at those .ID fields and values. .ID values for item does not change over time.