I have a Web service for creating user session basically its a login web service. This web service basically creates a session key so that for every web service that i need to access is I need to attach this Session ID in my header, my question is where is the good place to store this session ID, I'm basically newbie in mobile development that has session id, not like web applications, browser have cookies and sessions, but how about in mobile application? Is it okay to save it in SQLite database? or there's other way to store this session ID? So that even though the user close the app and reopens it, the session will restore.
by the way, I'm using xamarin to create my mobile applications, I'm actually thinking if there's a storage that I can use to store and restore my session id in both iOS and android.
Thanks
I would suggest creating a private SharedPreferences for your App, and holding the value there. But then i would also suggest having the session expire every so often so that if the users phone was stolen, they would not be able to log in to your application and get information assuming that the expiration time was reached.
To save to shared preferences:
// create a String for the SharedPreferences
private static final String PREFS = "MyAppsPrivatePrefs";
private static final String SESS_KEY = "Session";
private String session = "";
// then access preferences
SharedPreferences sharedPrefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE);
// Open preferences for editting
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(SESSION, session);
editor.commit();
This should work but again I would suggest adding logic to clear this if some time has passed...
You can work with SharedPreferences.
http://developer.android.com/reference/android/content/SharedPreferences.html
The preferences will be removed only if the user clear the cache!
If you are using android (not Xamarin) then Use SharedPreferences classes in android and set your user session and get user session.I written code as. First Create SharedPreferences class named DataStore as
package com.example.examplesharedpreferenced.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class DataStore {
private static final String PREF_NAME = "com.example.examplesharedpreferenced.pref";
public static final String KEY_SESSION = "key_session";
public static void setUserSession(Context context, String session) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
PREF_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
editor.putString(KEY_SESSION, session);
editor.commit();
}
public static String getUserSession(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(KEY_SESSION, null);
}
}
Then use theses above methods in Main Activity like
package com.example.examplesharedpreferenced;
import com.example.examplesharedpreferenced.utils.DataStore;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get user session
String userSession = DataStore.getUserSession(MainActivity.this);
Log.d(TAG, "userSession : "+userSession);
//setting user session
DataStore.setUserSession(MainActivity.this, "abc345asd");
//get user session after setting it.
String userSessionAfter = DataStore.getUserSession(MainActivity.this);
Log.d(TAG, "userSessionAfter : "+userSessionAfter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
For Xamarin you should follow link
Related
I am testing my mobile app using Appium. When app starting it directly navigation to HomeActivity sometimes(if user already logged in). If user not logged in then opening LoginActivity.
So, how can I know which activity starting? so that I can execute logout code accordingly.
This code not executing at all because app navigation to HomeActivity directly instead of LoginActivity.
public void DemoTest()
{
AndroidElement editElement1 = driver.FindElementById("input_name");
editElement1.Clear();
editElement1.SendKeys("ak#ct");
AndroidElement editElement2 = driver.FindElementById("input_password");
editElement2.Click();
editElement2.SendKeys("qa");
driver.HideKeyboard();
driver.Manage().Timeouts().ImplicitWait =TimeSpan.FromSeconds(4);
AndroidElement editElement3 = driver.FindElementById("btnLogin");
editElement3.Click();
}
If you always want to test in fresh app, you can add noReset = false capability in your DesiredCapabilities.
If you want to check which screen is visible, there must be unique element or id in the homeActivityScreen and LoginActivityScreen. Then you can use isDisplayed() function.
If you use Page Object Model it will be very easy for you to check which screen is Display.
I am going to show sample of page object model in java code. Hope you can convert it into C# code
public class HomeActivityScreen {
//you can use accessibility, id or xpath
#AndroidFindBy(id = " your element id")
private MobileElement element1;
#AndroidFindBy(id = "element id")
private MobileElement element2;
public HomeActivityScreen(AppiumDriver<MobileElement> driver) {
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
public boolean isScreenDisplayed() {
try {
return element1.isDisplayed();
} catch (Exception e) {
return false;
}
}
}
Similarly you can add page object model for other screen. Then in your test class you can check which screen is visible like
HomeActivityScreen homeScreen = new HomeActivityScreen(driver);
LoginActivityScreen loginScreen = new LoginActivityScreen(driver);
if(homeScreen.isScreenDisplayed){
//write your code
}else if(loginScreen.isScreenDisplayed){
//write logout code
}else{
//none of above screen is visible
}
You'll need a way to identify the page as being the home page or login page.
If you have access to the mobile app source code, you could give your home page a "homePage" AutomationId and your login page a "loginPage" AutomationId. If that is not possible, ask the developer to add them for you. Use these Id's in your appium code to uniquely identify the page that got loaded.
In your appium code, these are the steps you need to take:
Start your app: driver = new AndroidDriver<AndroidElement>(url, cap);
Give the app some time to get loaded.
Check what page you are on, e.g. by checking the AutomationId or a other unique value for those pages.
In your test script, you can do it like this:
try
{
control = driver.FindElementByAccessibilityId("loginPage");
}
catch (Exception ex)
{
// No login page found, your in the home page.
// Code for logging out here.
}
As Suban Dhyako already suggested, a page object design pattern is a very good practice. It keeps your code clean and clear to read. You can read more about it here.
Due to a problem caused by having multiple forms on a single page, I used an AJAX call to a WebMethod to submit my form instead of using ASP controls. However, in doing this, the previous method I had used to create a new entry into my database no longer works because a WebMethod must be static.
I have authenticated my user already using ASPX authentication, and am trying to retrieve the username and ID of that user with codebehind. The user has already been authenticated on Page_Load, but it seems I cannot access this information through my WebMethod. Is this possible to do inside of a static WebMethod? Thank you for all of your help in advance!
[WebMethod]
public static void CreateJob()
{
Submit_Job();
}
public static void Submit_Job()
{
if (Page.User.Identity.IsAuthenticated)
{
try
{
string username = Context.User.Identity.Name;
}
catch
{
Context.GetOwinContext().Authentication.SignOut();
}
}
var manager = new UserManager();
var usernameDatabase = new ApplicationUser() { UserName = username };
usernameDatabase = manager.Find(username, "password here");
if (usernameDatabase != null)
{
IdentityHelper.SignIn(manager, usernameDatabase, isPersistent: false);
string jobTitle = Request.Form["jobTitle"];
using (var ctx = new CreateUserContext(ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString))
{
Job job = new Job()
{
job_title = jobTitle
};
ctx.Jobs.Add(job);
ctx.SaveChanges();
}
}
}
Edit:
There are errors for example with Page.User.Identity.IsAuthenticated -- Page, Context, and Request all appear that they cannot be static.
The specific error:
(An object reference is required for the non-static field, method, or property 'Control.Page') as well as with Context and Request.
Moving it from a simple comment
I had the same issue recently.
Luckily, whenever a user signs in our application, we store the user information encrypted into a session variable, so I retrieve that information, pass it to our user's class constructor, which decrypts it and I can use my logged in users info without a hassle.
So, my solution is to store the users info in the Session, but be careful what you store. Maybe serialize the users object and store in the session, then, whenever you need it
public void Page_Load()
{
// Retrieve authenticated user information
UserClass userObject = GetUserCredentials();
// Call a method that turns the authenticated user object into a string that contains the users session information. Given the sensivity of this information, might want to try to encrypt it or offuscate it. Store it in a session variable as a string
Session["UserContext"] = userObject.SerializeUser()
/* rest of the page code goes here */
}
[WebMethod(EnableSession=true)]
public static void CreateJob()
{
Submit_Job();
}
public static void Submit_Job()
{
// Lets get the authenticated user information through the session variable. Due to the static nature of the method, we can't access the Session variables directly, so we call it using the current HttpContext
string serializedUserInfo = )HttpContext.Current.Session["UserContext"].ToString();
// Let's create the users object. In my case, we have a overcharged constructor that receives the users serialized/encrypted information, descrypts it, deserializes it, and return a instance of the class with the deserialized information
UserClass userObject = new UserClass(serializedUserInfo);
// Do whatever the method has to do now!
}
On the subject of serialization, a quick google search with "c# object serialization" will bring you several good matches. XML and JSON are 2 of the most used kind of serialization, specially on web methods. Binary serialization is a good option to also obfuscate information of the logged in user
I am developing a Windows Service that submits some data to a web api. As Part of this I need to submit a GUID that I am generating with
Guid.NewGuid():
This GUID would be individual per machine, never change, and be the same for all users who log in. I'm struggling with where to actually store this though. I came across the Properties.Setting which seemed perfect, but if I scope to Application instead of User, it won't let me set the property as it is read only.
How and where do I store the GUID? It will only generate once (when the service starts on a PC for the first time).
In your case, you can use the ConfigurationManager Class in order to access and write the GUID in your application setting. From the link above example:
static void AddUpdateAppSettings(string key, string value)
{
try
{
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (settings[key] == null)
{
settings.Add(key, value);
}
else
{
settings[key].Value = value;
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
}
catch (ConfigurationErrorsException)
{
Console.WriteLine("Error writing app settings");
}
}
you can use it like:
AddUpdateAppSettings("MachineGuid", Guid.NewGuid().ToString());
I'm using a WebBrowser control to automate management of a web page. When I start my WPF application, it shows the webpage ant lets me login. Then my application starts to do some automated tasks by going to a page, filling a form and submitting (it’s a POST-form). It submits the same form ~100 times with different values.
Right now my code is as follows:
void webBrowser1_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
var doc = (HTMLDocument) webBrowser1.Document;
var form = doc.getElementById("theForm");
SetValueOfFormInput(doc, "id", Foo.ID);
SetValueOfFormInput(doc, "item1", Foo.Item1);
SetValueOfFormInput(doc, "item2", Foo.Item2);
form.all.item("submit").click();
}
private static void SetValueOfFormInput(HTMLDocument doc, string name, string value)
{
var item = doc.all.item(name);
item.setAttribute("value", value);
}
Can I do this on a better way and can I do it in a MVVM way?
And no, I can't modify the the webpage to do the management easier :-(
Edit:
Ideally, I would be able to do this without having to use the WebBrowser control. The program logon to the website and performs all tasks without having to modify the forms in the html pages
Why not using the WebClient or WebRequest classes?
For the webclient, you can use the UploadValues method which will do exactly what you want (http://msdn.microsoft.com/en-us/library/9w7b4fz7.aspx) and you can also simply addapt the class to use cookies so your login will be "permanent" (http://stackoverflow.com/questions/1777221/c-using-cookiecontainer-with-webclient-class)
If you like to do it even more model driven, i would use the WebRequest (has allready a cookiecontainer) and have some class with the needed data. This one would derive from a class, which can serialize all needed properties into a simple string you would post to the server - AFAIK it's same like the getter-parameters (param1=val1¶m2=val2&...)
so basically:
class Data : Postable { public string Param1{get;set;} public string Param2{get;set;} ...}
class Postable
{
public override string ToString()
{
StringBuilder ret = new StringBuilder();
foreach(Property p in GetType().GetProperties())
{
ret.Append("{0}={1}&", p.Name, p.<GetValue>);
}
return ret.ToString();
}
}
Hi can I'm very new to windows forms. Here I want to maintain state (like session in web applications) in windows forms.
Actually i want to store user login details in session. But i think there is no concept of session in winforms. So what is the alternative method to handle this type of situation.
Regards,
Nagu
There is no concept of Session variables in windows forms. What you can do is:
Create a internal class that holds the User name and password and any other variables and enumerations needed across the application (Something like Common.cs). These can be accessed through public properties across the application.
Have a parameterized constructor for all the forms and send the user name and the password whenever you are showing the form.
public class MyForm : Form
{
private string userName;
private string password;
}
Since windows forms are statefull (opposed to stateless for web forms), you can just use a field in your Form class.
You need to think more in terms of scope than session; as long as an object remains in scope you will be able to pull values from its public properties/fields.
In your case it would make sense to store the user details in a static class:
public static class LoginInfo
{
public static string UserID;
}
Now you can access the UserID simply from anywhere in your code:
MessageBox.Show(LogInfo.UserID);
In winforms you can use variables that are exposed to other forms through methods or properties.
You can also use static variables.
In the following example, you would have a controller for each window or group of windows. The controllers would be passed to one another depending on how they need to collaborate (what knowledge they need to share, etc). The important thing is to keep your application state in the controllers and limit the windows to handling user input and events.
// pseudocode, because I do not know WinForms that much
class MainController
{
private Guid securityToken;
public Guid SecurityToken
{
get { return securityToken; }
set { securityToken = value; }
}
}
class LoginWindowController
{
MainController mainController;
LoginWindow loginWindow;
public LoginWindowController(MainController mainController)
{
this.loginWindow = new LoginWindow(this);
this.mainController = mainController;
}
public void Show()
{
loginWindow.IsVisible = true;
}
public void HandleLogin()
{
Guid token =
myobject.Authenticate(loginWindow.Username, loginWindow.Password);
if (token != Guid.Empty)
{
mainController.SecurityToken = token;
}
}
}
In reply to your comment to my first reply:
You are creating the new instance of the Login form. How is that supposed to have values. It is a Login form and hence I believe you will be closing it as the user enters user name and password and clicks OK or whatever.
Then, there is no way you can get the values from the Login form as it is closed. If you need to stick to this approach, this could be a way:
Do not close the Login form, just hide it.
Pass the current instance to the next form. Like this:
In Login form:
NextForm nxt = new NextForm(this);
The constructor of NextForm will look like:
public NextForm(LoginForm frm){
// Code here
}
Now in NextForm, you can access the properties through "frm".
from a program i was using with a login form to store global variables and to store the password as a secure string. Within the program I am able to "run as" a specific user when I call processes. You can use it for other things besides process.start.
//to run process as another user
//create these global variables on the first
//form or piece of code in your program
class usernameGlobalVariable
{
public static string var = "";
}
class passwordGlobalVariable
{
public static SecureString var;
}
// use these as event handlers for text fields
//for your login form
private void usernameTextBox_TextChanged(object sender, EventArgs e)
{
usernameGlobalVariable.var = usernameTextBox.Text;
}
private void passwordTextBox_TextChanged(object sender, EventArgs e)
{
SecureString passWord = new SecureString();
foreach (char c in passwordTextBox.Text.ToCharArray())
{
passWord.AppendChar(c);
}
passwordGlobalVariable.var = passWord;
}
//put this on form that launches program
//this assigns variables for process.start
//change fileName to path and name of program
// use \\ in paths
string fileName = "c:\\hdatools\\Ping2.exe";
string arguments = "";
string domain = "domain";
//start the process
//put this on the page along w the above variables that
//launches the app as another user
//the .var variables are global
{
Process.Start(
fileName,
arguments,
usernameGlobalVariable.var,
passwordGlobalVariable.var,
domain);
}
It's unclear to me whether you are talking about a web application or a stand along application based upon one of your responses. If you are talking about a web application, you can use the Session properties on the Page object.
It would set the variables like this:
Session["username"] = "Username";
Session["fullname"] = "User's full name";
You could then access like:
lblGreetings.Text = "Hi " + Session["fullname"];
Is that what you were after?