I try to set a http autentification with android
this is my class
http://pastebin.com/SB9TKtQZ
I use like this
EditText user = (EditText)findViewById(R.id.referent_login_input);
EditText password = (EditText)findViewById(R.id.referent_password_input);
Api login = new Api(getString(R.string.api_url));
login.updateUrl("login");
login.updateHeader(user.getText().toString(), password.getText().toString());
String connect = login.get();
My php is
if( !isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']) ) {
echo "no !!!";
}
else {
echo "yes";
}
and I always have no !!!
I set something in my EditText
Thanks
Related
The pin code and user name works fine in postman but whenever i call from the app it returns 404 response. And also in postman it doesnt need any header.
I have tried changing the order of the code lines but nothing seem to work.
android permission of internet is taken in manifest too.
pin = "pin_code = 1111";
uname = "username = bruce";
AsyncTask.execute(new Runnable() {
#Override
public void run() {
HttpsURLConnection connect = null;
try {
getApi = new URL("https://portal.hal.com/users/api/patient/login/with_username/");
connect = (HttpsURLConnection) getApi.openConnection();
connect.setDoInput (true);
connect.setDoOutput(true);
connect.setRequestMethod("POST");
connect.connect();
connect.getOutputStream().write(pin.getBytes());
connect.getOutputStream().write(uname.getBytes());
connect.getOutputStream().close();
if (connect.getResponseCode() == 200 ) {
Log.d(TAG,"DONE");
} if (connect.getResponseCode() == 404){
Log.d(TAG,"404 error");
}
Found the mistake. in username and password string are both sent in one string.
String parameter = "pin_code=4444&username=user";
connect.getOutputStream().write(parameter.getBytes());
To login with facebook on my android app I request the public_profile and email of the user:
LoginManager.getInstance().logInWithReadPermissions(LoginFragment.this,
Arrays.asList("public_profile", "email"));
Then I send the id_token Profile.getCurrentProfile().getId() to the backend server.
On server side I try to verify the token as follows:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$response = $fb->get('/debug_token?input_token=' . $id_token, $app_access_token);
But $response just contains an empty json {}.
UPDATE 1:
With
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
I eventually managed to validate the id_token. $meta contains then:
["metadata":protected]=>
array(4) {
["app_id"]=>string(16) "123456"
["application"]=>string(10) "abcdef"
["is_valid"]=>bool(true)
["scopes"]=>array(0) {}
}
What it also shows is that the scopes-array is empty although I called logInWithReadPermissions with public_profile and email permissions. I even checked the Permissions again in the onSuccess()-method of the FacebookCallback. But before I store the data to the DB I would like to read the user_id, user_name and email on server side to ensure that they match the id_token.
UPDATE 2:
When I call $oauth->debugToken() with $id_token instead of $app_access_token I now get what I expected. It also shows the pemissions I set before. But still I have the problem that I don't know how to access the granted information (user_name, user_profile_picture, email, etc.).
Finally I managed to solve the whole problem. I guess my main problem was that I wasn't aware of when to use user access token and when app access token. In many discussions and even documentations one is just talking about access token without specifying whether he means the user or the app access token. That said, here my final solution:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
try {
$meta->validateAppId(FB_APP_ID);
$idTokenIsValid = true;
} catch(FacebookSDKException $e) {
$idTokenIsValid = false;
exit;
}
if($idTokenIsValid){
$resp = $fb->get('/me?fields=id,name,email,first_name,last_name,locale,gender', $id_token);
$user = $resp->getGraphUser();
if($user->getId() != null){
$facebook_id = $user->getId();
$picture = "graph.facebook.com/" . $facebook_id . "/picture";
}
if($user->getName() != null){
$name = $user->getName();
}
$emailIsVerified = false;
if($user->getEmail() != null){
$email = $user->getEmail();
$emailIsVerified = true;
}
if($user->getFirstName() != null){
$given_name = $user->getFirstName();
}
if($user->getLastName() != null){
$family_name = $user->getLastName();
}
if($user->getProperty('locale') != null){
$locale = $user->getProperty('locale');
}
if($user->getProperty('gender') != null){
$gender = $user->getProperty('gender');
}
if($emailIsVerified){
//update db or/and request data from db
}
}
I want to make a diet helper app for android devices, using android studio and
I need ideas on what to use to implement the login/register system, I followed a tutorial on youtube but it was outdated and I ended up wasting my time, then I've read on google, that android studio has a library called volley that I can use with PHP and MySql to make the login system.
Do you have other ideas, or is that the best one to go with?
I'm open to suggestions so shoot!
Update:
I've created a post about how to do this using a PHP backend for your Android application. https://keithweaver.ca/posts/4/android-php-custom-login
Additionally to the link above, this is how you can setup a server.
https://github.com/kweaver00/tutorials/blob/master/setup-server.md
https://keithweaver.ca/posts/9/setup-ubuntu-server-quickly
Original Post:
This is one solution and isn't guaranteed to be the best.
You can really use anything to communicate with a server. Async Tasks or Retrofit are both popular.
Assuming you have set up a server with a LAMP stack. Make sure you have an SSL so you don't pass user information that isn't encrypted.
Create a user table in mysql
Ex.
id int default->NULL AI primary-key
user varchar 250 default->null
pass varchar 250 default->null
signupdate date default-> null
Create a log in sessions table of some sort
Ex.
id int default->NULL AI primary-key
user varchar 250 default->null
token varchar 250 default->null
addedDate date default->null
Create a log in php script (I know this probably isnt the best way to right php code)
$connection = mysqli_connect("localhost", "phpmysqluser", "password", "dbname") or die("Error 404: unable to connect");
$username = $_POST['user'];
$pass = $_POST['pass'];
//add code to remove slashes and etc.
$result = mysqli_query($connection, "SELECT * FROM userTable WHERE user='$username' AND pass='$pass'") or die("Error: this line has error");
class response{
public $loggedin =0;
public $message = "";
}
$response = new response();
if(mysqli_num_rows($result) == 1){
$logInToken = generateLogInToken();
//have a function that creates a unique token and stores it for X days or minutes
$response->loggedin = 1;
$response->message = $logInToken;
}else{
$response->message = "wrong info";
}
echo json_decode($response);
This should output a json file like this depending on your user and pass variables.
{
"loggedin" : 1,
"message" : "asdnlansdkansd"
}
Right another script that passes in the log in token and user name to check if it's valid.
$connection .... //same as above
//well it really should be a include_once cause if you change credentials
$token = $_POST['token'];
$user = $_POST['user'];
$registeredDate = "";
$today = date('Y-m-d');
$result = mysqli_query($connection, "SELECT * FROM tokenTable WHERE user='$user' AND token='$token'") or die("Error...");
class response{
public $status = 0;
}
$response = new response();
if(mysqli_num_rows($result) == 1){
//check token has been register today and if not sign them out
while($row = mysqli_fetch_array($result)){
$registeredDate = $row['addedDate'];
}
if($registeredDate == $today){
//token is valid
$response->status = 3;
}else{
//expired
$response->status = 2;
}
}else{
//user and token are not valid
$response->status = 1;
}
echo json_decode($response);
Giving a json object like:
{
"status" : 3
}
In your Android app on open, run the code to check if the account is valid if there is anything stored locally. Or just go to log in screen.
On splash screen in the onCreate (you dont need a splash screen, its actually not recommended but its the easiest way to explain the process):
if(userNameAndTokenStoredInSharedPref()){
String token = getTokenFromSharedPref();
String userName = getUserNameFromSharedPref();
checkAgainstServer(token, userName);
}else{
Intent openLogInWindow = new Intent(this, LogInActivity.class);
startActivity(openLogInWindow);
}
still in the slash activity but out of the oncreate:
protected void checkAgainstServer(String token, String user){
//using retrofit
ThisAppRestClient.get().postCheckTokenAndUser(token, user, new Callback<UserStatusCallBack>() {
#Override
public void success(UserStatusCallBack userStatusCallback, retrofit.client.Response response) {
if(userStatusCallback.getStatus() == 1){
//Invalid token
}else if(userStatusCallback.getStatus() == 2){
//Expired token
}else if(userStatusCallback.getStatus() == 3){
//Success
Intent openMainWindow = new Intent(this, MainActivity.class);
startActivity(openMainWindow);
}
}
#Override
public void failure(RetrofitError error) {
//Retrofit errors like timeouts, etc.
}
}
}
The log in activity would be something like:
logBtn.setOnClickListener(new View.onClick...
String userName = userNameEditText.getText().toString().toLowerCase().trim();
String password = passwordEditText.getText().toString().trim();
if(!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(password)){
callServerLogInScript(userName, password);
}
userNameEditText.setText("");
logBtn.setVisibility(View.GONE);
}
lower down the file:
protected void callServerLogInScript(String user, String pass){
//using retrofit
ThisAppRestClient.get().postCheckTokenAndUser(user, pass, new Callback<LogInCallBack>() {
#Override
public void success(LogInCallBack logInCallback, retrofit.client.Response response) {
if(logInCallback.getLoggedIn() == 1){
//succssful
storeUserNameInSharedPref(user);
storeTokenInSharedPref(logInCallback.getMessage());
Intent openMainActivity = new Intent(this, MainActivity.class);
startActivity(openMainActivity);
}else{
//incorrect log in
logBtn.setVisibility(View.VISIBLE);
}
}
#Override
public void failure(RetrofitError error) {
//Retrofit errors like timeouts, etc.
}
}
}
The reason for not storing the user name and password directly is if the device is rooted they can manipulate the data locally but not on your server.
It depends which you want to use. If you have your own server to host, then use php,mysql. If not, you can also use other third party which provides you to add if you know php,mysql to create.
Another option is if you don't want to use php mysql to store datas, then you can proceed with parse.com
So if you want to use parse.com, just register it. It's free to use.
Hope it will match your requirement, say for eg: if you want to create registration(everything saving in datas will be handled),you need to give exact object name that matches what you given in parse.com
Even you can also create in code itself without object name. I will show you a piece of example how to create and insert for registration..
ParseUser user = new ParseUser();
user.setEmail((txtEmail));//create an edittext and get the values in strings and store..
user.setPassword(txtPassword);//same for password
user.setUsername(txtUsername);//username
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
//completed..it has been registered
Toast.makeText(getApplicationContext(),
"Successfully Signed up, please log in.",
Toast.LENGTH_LONG).show();
finish();
} else {
Toast.makeText(getApplicationContext(),
"Sign up Error", Toast.LENGTH_LONG)
.show();
}
}
});
Simple one if you don't want to use php,mysql. Well documentation and easy to integrate and use it. Happy coding.
FYI: Android studio is IDE for development. And volley is HTTP library that makes networking for Android.
So I've been using javamail API as part of my android app. After a login to a gmail account, the user can write new emails, check the inbox and sent mails. The emails are displayed in a listview with the help of an adapter class. (more accurately the sender, the subject and the sending date is displayed, and if the user clicks on the listview item, then the mail content will be displayed too on a new activity). All this is working well.
I would like to display unread emails differently (unread in the gmail client too), like set the textSyle bold if the mail is unread, but i'm having trouble adding this feature. I've been trying to check the flags of each fetched email message, but for some reason i dont see these flags in the variables.
My code snippet for fetching the mails (display is not here, that's in the adapter class):
protected ArrayList<Email_Message> doInBackground(Void... args) {
try {
Properties properties = new Properties();
properties.put("mail.store.protocol", "imaps");
Session emailSession = Session.getDefaultInstance(properties);
Store store = emailSession.getStore("imaps");
store.connect("imap.gmail.com", username, password);
// create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_WRITE);
Flags flags2 = emailFolder.getPermanentFlags(); //has 2 weird user flags in it ($phishing, $notphising) and systemflags = -2147483061 ???
Flags seen = new Flags(Flags.Flag.RECENT);
FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
Message messages2[] = emailFolder.search(unseenFlagTerm); //this will net the same result as getMessages(), only here for testing
int test = emailFolder.getUnreadMessageCount(); //as far as i can tell this is working (i have 5000+ emails and 37 them are unread somewhere) but when i get a new email and the number goes up by 1 (38), and if i run the code again, after i already fetched the mails once, it's gonna be 37 again, and the mail marked as read in my gmail webclient too
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
int j = messages.length - 1;
for (int i = j - startIndex; i > j - startIndex - offset && i > (-1); i--) { //startIndex and offset are for displaying only 10 messages at the start and loading another 10 if the user scrolls to bottom
if (isCancelled()){
break;
}
Email_Message mailMessage = new Email_Message(); //my class for storing email messages
mailMessage.messageType = 1;
//some tricks to get the address in the right format
Address[] email_address = messages[i].getFrom();
String tempAddress = email_address[0].toString();
tempAddress = MimeUtility.decodeText(tempAddress);
//still tempering with address, not important
if(tempAddress.contains("=?")){
String[] AddressParts = tempAddress.split("\\?=");
mailMessage.messageAddress = AddressParts[1].substring(2);
}
else {
mailMessage.messageAddress = tempAddress;
}
Flags flags = messages[i].getFlags(); //user_flags = null, system_flags = 32
Flags.Flag[] systemflags = flags.getSystemFlags(); //has 1 item in it: bit = 32
String str[]= flags.getUserFlags(); //empty, these are all true for all my mails, not just one
mailMessage.messageDate = messages[i].getSentDate().toString();
mailMessage.messageSubject = messages[i].getSubject();
Object msgContent = messages[i].getContent();
String content = ""; //getting the content of the mail with these multipart stuffs
if (msgContent instanceof Multipart) {
Multipart multipart = (Multipart) msgContent;
Log.e("BodyPart", "MultiPartCount: " + multipart.getCount());
for (int k = 0; k < multipart.getCount(); k++) {
BodyPart bodyPart = multipart.getBodyPart(k);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equalsIgnoreCase("ATTACHMENT"))) {
DataHandler handler = bodyPart.getDataHandler();
content = handler.getName();
} else {
content = bodyPart.getContent().toString();
}
}
} else
content = messages[i].getContent().toString();
mailMessage.messageContent = content;
EmailInbox.add(mailMessage);
}
// close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return EmailInbox;
}
I put some comments in the code to explain what i've found in the flags. What can I do to make this work? I already predict problems, like what happens after I read an unread mail in my app only, set its flag to seen, and when I start the activity again and fetch the mails, it's gonna be unread again, since I don't store them locally, but that's a problem after I managed to find a solution for this first.
Thanks for any help!
I'm not clear on how you're looking for the flags. Using messages[i].isSet(Flags.Flag.SEEN) will tell you if the SEEN flag has been set. Note that the SEEN flag will normally be set as soon as you access the content of the message, so you should not have to set it yourself.
Hint: use the InternetAddress.toUnicodeString method, or get the name and address separately using the getPersonal and getAddress methods. This will avoid any need to decode them yourself.
in android Asmack i want to set invisible user.
and i used from every mode but it didn't works. after that i used from Type ..
when i set type unavailable, it works . but there is a problem .. my pocket listener doesn't work .. and i cant get any thing from user .. What can i do .. Thanks a lot.
Type type = Presence.Type.available;
Mode OWN = Mode.available;
if (DB_STATUS.avibilaty.toString().equals("")) {
OWN = Mode.available;
} else if (DB_STATUS.avibilaty.toString().equals("away")) {
OWN = Mode.away;
} else if (DB_STATUS.avibilaty.toString().equals(
"available")) {
OWN = Mode.available;
} else if (DB_STATUS.avibilaty.toString().equals(
"unavailable")) {
type = Presence.Type.unavailable;
} else if (DB_STATUS.avibilaty.toString().equals("busy")) {
OWN = Mode.dnd;
}
Presence presence = new Presence(type);
presence.setMode(OWN);