How to make php more secure in unity - javascript

I wish to update a table in a database using php. I'm developing a game in unity using php to retrieve and update data. Each user logs in with their FB details (the correct way by using the FB API), but for now the username is a unique int ID and a sc column that needs to be updated.
Here is a link example: http://www.mydomain.co.za/php/myphp2.php?id=1&sc="1,2"
PHP code (myphp2.php):
<?php
require_once('/home/########/public_html/php/mysqli_connect.php');
$id = $_GET['id'];
$selected_cards = $_GET['sc'];
$query = "UPDATE PlayerCards SET SelectedCards=$selected_cards WHERE ID=$id";
$response = #mysqli_query($dbc, $query);
if($response){
echo 'Updated the sc of the selected id';
} else {
echo 'could not execute database query 2';
}
?>
This way I can update any user's sc value using a browser. (BIG PROBLEM)
Here is my C# scripts for Unity that retrieves the facebook user's login ID that I will use in my database to store values:
FB_manager.cs: (script that contains data)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using Facebook.Unity;
public class FB_manager : MonoBehaviour {
private static FB_manager _instance;
public static FB_manager Instance
{
get {
if(_instance == null){
GameObject fbm = new GameObject("FBManager");
fbm.AddComponent<FB_manager>();
}
return _instance;
}
}
public bool IsLoggedIn {get; set;}
public string ProfileName {get; set;}
public Sprite ProfilePic {get; set;}
public string ProfileEmail {get; set;}
void Awake()
{
DontDestroyOnLoad(this.gameObject);
_instance = this;
}
public void InitFB(){
if (!FB.IsInitialized) {
// Initialize the Facebook SDK
FB.Init(InitCallback, OnHideUnity);
} else {
IsLoggedIn = FB.IsLoggedIn;
}
}
private void InitCallback()
{
if (FB.IsInitialized) {
Debug.Log("FB is logged in");
GetProfile();
FB.ActivateApp();
} else {
Debug.Log("FB not logged in");
}
IsLoggedIn = FB.IsLoggedIn;
}
private void OnHideUnity(bool isGameShown)
{
if (!isGameShown) {
// Pause the game - we will need to hide
Time.timeScale = 0;
} else {
// Resume the game - we're getting focus again
Time.timeScale = 1;
}
}
public void GetProfile(){
FB.API("/me?fields=first_name",HttpMethod.GET, DisplayUserName);
FB.API("/me/picture?type=square&height=128&&widht=128",HttpMethod.GET, DisplayProfilePic);
FB.API("/me?fields=email",HttpMethod.GET, DisplayUserEmail);
}
void DisplayUserName(IResult result){
if(result.Error == null){
ProfileName = "" + result.ResultDictionary["first_name"];
} else {
Debug.Log(result.Error);
}
}
void DisplayUserEmail(IResult result){
if(result.Error == null){
Debug.Log(result);
ProfileEmail = "" + result.ResultDictionary["id"];
} else {
Debug.Log(result.Error);
}
}
void DisplayProfilePic(IGraphResult result){
if(result.Texture != null){
ProfilePic = Sprite.Create(result.Texture, new Rect(0,0,128,128), new Vector2());
} else {
Debug.Log(result.Error);
}
}
}
FB_script.cs: (script that contains data)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using Facebook.Unity;
public class FB_script : MonoBehaviour {
public GameObject DialogLoggedIn;
public GameObject DialogLoggedOut;
public GameObject logInStatusLabel;
public GameObject Name;
public GameObject ProfilePic;
void Awake()
{
FB_manager.Instance.InitFB();
HandleMenu(FB.IsLoggedIn);
}
public void FBLogin() {
var perms = new List<string>() { "public_profile", "email", "user_friends", "publish_actions"};
FB.LogInWithReadPermissions(perms, AuthCallback);
}
private void AuthCallback(ILoginResult result)
{
if (FB.IsLoggedIn) {
HandleMenu(FB.IsLoggedIn);
Debug.Log("User logged in");
FB_manager.Instance.IsLoggedIn = true;
FB_manager.Instance.GetProfile();
// AccessToken class will have session details
var aToken = Facebook.Unity.AccessToken.CurrentAccessToken;
// Print current access token's User ID
Debug.Log(aToken.UserId);
// Print current access token's granted permissions
foreach (string perm in aToken.Permissions) {
Debug.Log(perm);
}
} else{
Debug.Log("User cancelled login");
}
HandleMenu(FB.IsLoggedIn);
}
void HandleMenu(bool isLoggedIn) {
if (isLoggedIn) {
DialogLoggedIn.SetActive(true);
DialogLoggedOut.SetActive(false);
logInStatusLabel.GetComponent<Text>().text = "Logged in as: ";
if(FB_manager.Instance.ProfileName!=null){
Text userName = Name.GetComponent<Text>();
userName.text = "" + FB_manager.Instance.ProfileName;
} else {
StartCoroutine("WaitForProfileName");
}
if(FB_manager.Instance.ProfilePic!=null){
Image image = ProfilePic.GetComponent<Image>();
image.sprite = FB_manager.Instance.ProfilePic;
} else {
StartCoroutine("WaitForProfilePic");
}
if(FB_manager.Instance.ProfileEmail!=null){
Text userName = Name.GetComponent<Text>();
userName.text = "" + FB_manager.Instance.ProfileEmail;
} else {
StartCoroutine("WaitForProfileEmail");
}
} else {
DialogLoggedIn.SetActive(false);
DialogLoggedOut.SetActive(true);
logInStatusLabel.GetComponent<Text>().text = "Not logged in";
}
}
IEnumerator WaitForProfileName(){
while(FB_manager.Instance.ProfileName==null){
yield return null;
}
HandleMenu(FB.IsLoggedIn);
}
IEnumerator WaitForProfilePic(){
while(FB_manager.Instance.ProfilePic==null){
yield return null;
}
HandleMenu(FB.IsLoggedIn);
}
IEnumerator WaitForProfileEmail(){
while(FB_manager.Instance.ProfileEmail==null){
yield return null;
}
HandleMenu(FB.IsLoggedIn);
}
}
I can connect to the database within Unity so that it access the database in order to update the table. Giving only update privileges when connecting within unity. The id and sc can then be enclosed by a script (embedding php into the script) to update the table. Will users be able to change the id inside the script? When deploying the game will user be able to edit scripts?

When a user logs in with Facebook credentials, then set their id in a session variable. Use the session variable in your sql query so that only the user can update their cards.

Related

SignalR server error while attempting to call a hub method

I use signalR in my project. It works fine. In a part on my project, I need to use instant notification when a delete button is clicked. The button is in jQuery datatable. I used the following code:
var connection = new signalR.HubConnectionBuilder().withUrl("/signalRServer").withAutomaticReconnect().build();
connection.start();
function DeleteData(pmId, mainFileName, fileName) {
if (confirm("Are you sure")) {
connection.invoke("PmPageUpdate", pmId).catch(function(err){
return console.error(err);
});
Delete(pmId, mainFileName, fileName);
} else {
return false;
}
}
When I debug, the hub method is not called. Console shows the following error:
PmManagement:692 Error: Failed to invoke 'PmPageUpdate' due to an
error on the server.
at H. (signalr.js:1:13973)
at L.I (signalr.js:1:14804)
at X.L.connection.onreceive (signalr.js:1:10649)
at WebSocket.r.onmessage (signalr.js:1:27565)
How can I fix this?
Update:
The followings are codes I've written for the hub. Some methods that are not related to this question has been ignored.
Hub:
private readonly IUserRepository _userRepository;
private readonly ICostCenterRepository _costcenterRepository;
private readonly IHttpContextAccessor _httpContext;
private readonly INotificationRepository _notificationRepository;
private readonly IMessageRepository _messageRepository;
private readonly IPmRepository _pmRepository;
public MessageHub(IUserRepository userRepository, ICostCenterRepository costcenterRepository, IHttpContextAccessor httpContext,
INotificationRepository notificationRepository, IMessageRepository messageRepository, IPmRepository pmRepository)
{
_userRepository = userRepository;
_costcenterRepository = costcenterRepository;
_httpContext = httpContext;
_notificationRepository = notificationRepository;
_messageRepository = messageRepository;
_pmRepository = pmRepository;
}
//define a dictionary to store the userid.
private static Dictionary<string, List<string>> NtoIdMappingTable = new Dictionary<string, List<string>>();
public Task JoinNotificationGroup(string groupName)
{
return Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
public Task LeaveNotificationGroup(string groupName)
{
return Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
public override async Task OnConnectedAsync()
{
var username = Context.User.Identity.Name;
var userId = Context.UserIdentifier;
List<string> userIds;
//store the userid to the list.
if (!NtoIdMappingTable.TryGetValue(username, out userIds))
{
userIds = new List<string>();
userIds.Add(userId);
NtoIdMappingTable.Add(username, userIds);
}
else
{
userIds.Add(userId);
}
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
var username = Context.User.Identity.Name;
//remove userid from the List
if (NtoIdMappingTable.ContainsKey(username))
{
NtoIdMappingTable.Remove(username);
}
await base.OnDisconnectedAsync(exception);
}
string username = _userRepository.GetUsernameByCostCenter(pmId).ToString();
var userId = NtoIdMappingTable.GetValueOrDefault(username);
await Clients.User(userId.ToString()).SendAsync("SignalReceiver");
}

How can i do if i want user and admin display different layout after login?

My mobile application got 2 account types of users which are admin and user. How can I do if I want user and admin display different layout after login? This is my login activity. Someone can help me, please? I'm a beginner. Thanks. Or anyone got any link that guide beginner to do these also can post it at here. Pretty much thanks for everyone.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
connectionClass = new ConnectionClass();
edtuserid = (EditText) findViewById(R.id.edtuserid);
edtpass = (EditText) findViewById(R.id.edtpass);
btnlogin = (Button) findViewById(R.id.btnlogin);
pbbar = (ProgressBar) findViewById(R.id.pbbar);
pbbar.setVisibility(View.GONE);
shp = this.getSharedPreferences("UserInfo", MODE_PRIVATE);
String userid = shp.getString("UserId", "none");
if (userid.equals("none") || userid.trim().equals("")) {
} else {
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
finish();
}
btnlogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DoLogin doLogin = new DoLogin();
doLogin.execute("");
}
});
}
public class DoLogin extends AsyncTask<String,String,String>
{
String z = "";
Boolean isSuccess = false;
String userid = edtuserid.getText().toString();
String password = edtpass.getText().toString();
#Override
protected void onPreExecute() {
pbbar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String r) {
pbbar.setVisibility(View.GONE);
Toast.makeText(LoginActivity.this,r,Toast.LENGTH_SHORT).show();
if(isSuccess) {
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
finish();
}
}
#Override
protected String doInBackground(String... params) {
if(userid.trim().equals("")|| password.trim().equals(""))
z = "Please enter User Id and Password";
else
{
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = "Error in connection with SQL server";
} else {
String query = "select * from dbo.demo where UserId='" + userid + "' and Password='" + password + "'";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
if(rs.next())
{
z = "Login successfull";
isSuccess=true;
}
else
{
z = "Invalid Credentials";
isSuccess = false;
}
}
}
catch (Exception ex)
{
isSuccess = false;
z = "Exceptions";
}
}
return z;
}
}
I did this kind of project once. To overcome this login issue, we added a column in our database as "role" which contains role as admin,user and etc. Create 2 different pages for admin and user. After checking the login credentials check the role also then redirect accordingly.

Display message in a toastr after controller method finish

i have controller method that upload image file, not using jQuery AJAX, from <input> type "file", the method returns:
Return Redirect(Request.UrlReferrer.PathAndQuery)
Because i want to stay in the same view after the submit click.
I want to show after the success image upload, toastr.success.
How i can do it?
In your http post action method, after successful upload, set an entry to TempData dictionary and read it in the next view which is loaded by the Redirect method and display the toastr message.
TempData["Msg"] = "Uploaded successfully";
return Redirect(Request.UrlReferrer.PathAndQuery);
in your view
<script>
$(function(){
var msg = "#(TempData["Msg"] as string)";
if (msg !== "") {
toastr.success(msg);
}
});
</script>
There is another way.
Create a Toastr model that includes Message, Title, Type, SessionID and Date.
public class Toastr
{
public string Title { get; set; }
public string Message { get; set; }
public ToastrType Type { get; set; }
public string SessionId { get; set; }
public DateTime Date { get; set; }
public Toastr(string message, string title = "Information" , ToastrType type = ToastrType.Info)
{
this.Message = message;
this.Title = title;
this.Type = type;
this.Date = DateTime.Now;
}
}
public enum ToastrType
{
Info = 0,
Success = 1,
Warning = 2,
Error = 3
}
Create a Service or Manager where you define your basic functions (add, remove toasts)
private static List<Toastr> _toasts = new List<Toastr>();
private static string GetSession()
{
return HttpContext.Current.Session.SessionID;
}
public static void AddToUserQueue(Toastr toastr)
{
toastr.SessionId = GetSession();
_toasts.Add(toastr);
}
public static void AddToUserQueue(string message, string title, ToastrType type)
{
var toast = new Toastr(message, title, type);
toast.SessionId = GetSession();
AddToUserQueue(toast);
}
public static bool HasQueue()
{
return _toasts.Any(t => t.SessionId == GetSession());
}
public static void RemoveUserQueue()
{
_toasts.RemoveAll(t => t.SessionId == GetSession());
}
public static void ClearAll()
{
_toasts.Clear();
}
public static List<Toastr> GetUserQueue()
{
if (HasQueue())
return _toasts.Where(t => t.SessionId == GetSession())
.OrderByDescending(x=>x.Date)
.ToList();
return null;
}
public static List<Toastr> GetAndRemoveUserQueue()
{
var list = GetUserQueue();
RemoveUserQueue();
return list;
}
In your layout / page make use of the functions by creating some helpers.
#helper ProcessToasts()
{
List<Toastr> toasts = ToastrManager.GetAndRemoveUserQueue();
if (toasts != null && toasts.Count > 0)
{
foreach (var item in toasts)
{
#ShowToastr(item);
}
}
}
#helper ShowToastr(Toastr item)
{
switch (item.Type)
{
case ToastrType.Info:
#ToastrInfo(item.Message, item.Title)
break;
case ToastrType.Success:
#ToastrSuccess(item.Message, item.Title)
break;
case ToastrType.Warning:
#ToastrWarning(item.Message, item.Title)
break;
case ToastrType.Error:
#ToastrError(item.Message, item.Title);
break;
}
}
#helper ToastrInfo(string message, string title)
{
<script>
toastr.info("#message","#title")
</script>
}
#helper ToastrSuccess(string message, string title)
{
<script>
toastr.success("#message","#title")
</script>
}
#helper ToastrWarning(string message, string title)
{
<script>
toastr.warning("#message","#title")
</script>
}
#helper ToastrError(string message, string title)
{
<script>
toastr.error("#message","#title")
</script>
}
Since the helpers are below closing HTML tag, you need just to add the #ProcessToasts() right before the body closing tag.

SignalR custom method to redirect

I have made SignalR custom methods to redirect users if they want to join group that already has 2 members. Everything seems to be working fine except the redirect method.
ChatHub.cs:
namespace SignalRChat
{
public class ChatHub : Hub
{
static string test2 = "";
public static Dictionary<string, int> rooms = new Dictionary<string, int>();
public void Test(string groupName)
{
if (!rooms.ContainsKey(groupName))
{
rooms.Add(groupName, 1);
}
else if(rooms[groupName] != 2)
{
rooms[groupName] = 2;
}
else
{
test2 = "testing";
Redirect();
}
}
public Task Redirect()
{
return Clients.Caller.redirectTo();
}
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
}
}
Scripts:
var chat2 = $.connection.chatHub;
$.connection.hub.start().done(function () {
chat2.server.test(roomId);
chat2.client.redirectTo = function () {
window.location.replace("http://stackoverflow.com");
}
chat2.server.joinGroup(roomId);
});
When there are already 2 clients in a group, test2 is set to "testing" but client does not get redirected.
Change your scripts to:
var chat2 = $.connection.chatHub;
// var roomId = "R1" <-- I added this for testing
chat2.client.redirectTo = function () {
window.location.replace("http://stackoverflow.com/questions/35848709/signalr-custom-method-to-redirect#35857376");
}
$.connection.hub.start().done(function () {
chat2.server.joinGroup(roomId);
chat2.server.test(roomId);
});
Note: in your Test method the logic says that the redirect will only run if rooms dictionary contains the given roomname and the int value corresponding to that roomname is '2'. Probably not your real planned logic.
For testing I added to the backed code:
public static Dictionary<string, int> rooms = new Dictionary<string, int>();
public void Test(string groupName) // <-- I sent "groupName: R1" from js
{
rooms["R1"] = 2;
if ...
}

Can't connect IExtension object to BrowserHelperObject

I'm trying to call a BHO plugin function from javascript, that BHO injected to page.
But:
console.log(window.myExtension) is "none" or "undefined"
OnDocumentComplete fires not on each browser start. (it's because of IE?)
OnDocumentComplete not fires on F5, just if set cursor in address field and press Enter (and see 2nd)
Complete code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Expando;
using SHDocVw;
using mshtml;
using Microsoft.Win32;
using INISpace;
namespace IEPlugin
{
[ComVisible(true),
Guid("4C1D2E51-018B-4A7C-8A07-618452573E42"),
InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IExtension
{
[DispId(1)]
void alert(string message);
}
// IObjectWithSite GUID
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}
[ComVisible(true),
Guid("DA8EA345-02AE-434E-82E9-448E3DB7629E"),
ClassInterface(ClassInterfaceType.None), ProgId("MyExtension"),
ComDefaultInterface(typeof(IExtension))]
public class BrowserHelperObject : IObjectWithSite, IExtension
{
private WebBrowser webBrowser;
public void alert(string message) { System.Windows.Forms.MessageBox.Show("BHO: " + message); }
public void OnDocumentComplete(dynamic frame, ref dynamic url)
{
if (!ReferenceEquals(frame, webBrowser))
{
return;
}
dynamic window = webBrowser.Document.parentWindow;
IExpando windowEx = (IExpando)window;
windowEx.AddProperty("myExtension");
//window.myExtension = this; crash that piece of shit
this.alert("frame IS browser" + windowEx);
HTMLDocument document = (HTMLDocument)webBrowser.Document;
IHTMLScriptElement scriptObject = (IHTMLScriptElement)document.createElement("script");
scriptObject.type = #"text/javascript";
scriptObject.text = "console.log(window.myExtension);";
document.appendChild((IHTMLDOMNode)scriptObject);
}
public int SetSite(object site)
{
if (site != null)
{
webBrowser = (WebBrowser)site;
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}
else
{
webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
webBrowser = null;
}
return 0;
}
public int GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
Marshal.Release(punk);
return hr;
}
public const string BHO_REGISTRY_KEY_NAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHO_REGISTRY_KEY_NAME, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(BHO_REGISTRY_KEY_NAME);
string guid = type.GUID.ToString("B");
RegistryKey ourKey = registryKey.OpenSubKey(guid);
if (ourKey == null)
{
ourKey = registryKey.CreateSubKey(guid);
}
ourKey.SetValue("NoExplorer", 1, RegistryValueKind.DWord);
registryKey.Close();
ourKey.Close();
}
[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHO_REGISTRY_KEY_NAME, true);
string guid = type.GUID.ToString("B");
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
}
}

Categories