我正在尝试让我的服务器从登录用户 (web) 获取 sso 并将其传递给 AS3 客户端。
如果我在客户端中设置特定的 SSO(如下所示),服务器将从数据库中获取用户。
目前我收到错误:错误 1:您的 SSO 票证无效。请重新登录,然后重新加载。
package
{
import com.archicruise.external.RoomManager;
import com.archicruise.server.Connection;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.system.Security;
import flash.system.System;
public class Main extends Sprite
{
[Embed(source = '../assets/client_back.png')] private static const clientBackImage:Class;
public static var SITE_URL:String = "http://localhost/archicruise/";
public var roomLoader:RoomManager;
private var connection:Connection;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//Add client background
addChild(new clientBackImage() as Bitmap);
//Got an SSO ticket?
var ssoTicket:String = LoaderInfo(this.root.loaderInfo).parameters["sso"];
if (ssoTicket == "" || ssoTicket == null) ssoTicket = "2e44550b0d6e98cc9f26c39e53213e24";
//Initialize the connection
Security.allowDomain("*");
connection = new Connection("localhost", 9339, this, ssoTicket);;
}
}
}
在用户登录网站并使用 SWF 启动页面后,我得到了 ssoTicket 值,如下所示:
var flashvars = {
sso: "<?php echo $self['sso_ticket']; ?>"
};
来自服务器的处理程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ParticleFramework.Communication;
using ParticleFramework.Storage;
using ParticleFramework;
using MySql.Data.MySqlClient;
using ArchiCruise.Rooms;
namespace ArchiCruise.Users
{
static class Handler
{
public static List<UserObject> clientObjects = new List<UserObject>();
public static void login(string ssoTicket, TcpClient client)
{
if (ssoTicket == "")
{
client.Disconnect();
return;
}
Log.Info("Client " + client.index + " logging in with SSO: " + ssoTicket);
if (DBManager.database.getString("SELECT COUNT(*) FROM users` WHERE sso_ticket like '%" + ssoTicket.Trim() + "%'") != "0")
{
DBManager.database.closeClient();
//build the user object
UserObject userObject = newObject(ssoTicket, client);
foreach (UserObject user in clientObjects)
{
if (user.username == userObject.username)
{
user.tcpClient.Disconnect();
}
}
if (clientObjects.Count <= client.index || clientObjects[client.index] == null)
{
client.userObject = userObject;
clientObjects.Add(userObject);
}
else
{
client.userObject = userObject;
clientObjects[client.index] = userObject;
}
client.sendData("LO" + (char)13 + userObject.ToPrivate());
DBManager.database.closeClient();
}
else
{
DBManager.database.closeClient();
client.sendData("ER 1: You have an invalid SSO ticket. Please re-login and then reload.");
}
}
public static void toAll(string Data)
{
foreach (UserObject user in clientObjects)
{
user.tcpClient.sendData(Data);
}
}
public static void toAll(string Data, Boolean disconnect)
{
foreach (UserObject user in clientObjects)
{
user.tcpClient.sendData(Data);
if (disconnect) user.tcpClient.Disconnect();
}
}
public static void toUser(string Data, string uname)
{
foreach (UserObject user in clientObjects)
{
if (user.username.ToLower() == uname.ToLower())
{
user.tcpClient.sendData(Data);
}
}
}
public static void toUser(string Data, string uname, Boolean disconnect)
{
foreach (UserObject user in clientObjects)
{
if (user.username.ToLower() == uname.ToLower())
{
user.tcpClient.sendData(Data);
if (disconnect)
{
user.tcpClient.Disconnect();
}
}
}
}
public static void toRoom(int roomID, TcpClient client)
{
if (clientObjects.Count >= client.index && client.userObject.roomID != roomID)
{
Log.Info("Client " + client.index + " going to public room " + roomID);
if (DBManager.database.getString("SELECT COUNT(*) FROM `public` WHERE `id` = '" + roomID + "';") != "0")
{
DBManager.database.closeClient();
//kick plz
if (client.userObject.roomID > 0)
{
client.userObject.toRoom("KO " + client.userObject.username);
}
//update user object
MySqlDataReader mysqlRead = DBManager.database.getCommand("SELECT * FROM `public` WHERE `id` = '" + roomID + "' LIMIT 1").ExecuteReader();
mysqlRead.Read();
client.userObject.toRoom(roomID, Convert.ToInt32(mysqlRead["startpos"].ToString().Split(',')[0]), Convert.ToInt32(mysqlRead["startpos"].ToString().Split(',')[1]));
client.sendData("RO" + mysqlRead["layout"].ToString() + (char)13 + mysqlRead["name"].ToString() + (char)13 + (char)12 + mysqlRead["heightmap"].ToString() + (char)12 + mysqlRead["warps"].ToString());
DBManager.database.closeClient();
}
else
{
DBManager.database.closeClient();
client.sendData("ER 1: You have an invalid SSO ticket. Please re-login and then reload.");
}
}
}
public static void moveUser(TcpClient client, int _x, int _y)
{
client.userObject.x = _x;
client.userObject.y = _y;
client.userObject.toRoom("MV " + client.userObject.username + " " + _x + " " + _y);
}
public static void sendNavigationList(TcpClient client, int pub)
{
string nList = "NV" + (char)13;
MySqlDataReader mysqlRead = DBManager.database.getCommand("SELECT * FROM `public` WHERE `show` = 'yes' AND `public` = '" + pub + "'").ExecuteReader();
while (mysqlRead.Read())
{
nList += mysqlRead["id"].ToString() + (char)14 + mysqlRead["name"].ToString() + (char)13;
}
DBManager.database.closeClient();
client.sendData(nList);
}
public static void sendUserList(TcpClient client)
{
string userList = "UE" + (char)13;
client.userObject.toRoom("UL" + (char)13 + client.userObject.ToString());
foreach (UserObject user in clientObjects)
{
if (user.roomID == client.userObject.roomID && user.tcpClient != null)
{
if (user.username != client.userObject.username && !userList.Contains(user.username + "@"))
{
userList += user.ToString();
}
}
}
client.sendData(userList);
//Send room object
client.sendData("RB" + (char)13 + RoomObjects.buildObjects(client.userObject.roomID));
}
public static UserObject newObject(string ssoTicket, TcpClient tClient)
{
MySqlDataReader mysqlRead = DBManager.database.getCommand("SELECT * FROM `users` WHERE `sso_ticket` = '" + ssoTicket + "' LIMIT 1").ExecuteReader();
mysqlRead.Read();
return new UserObject(mysqlRead["name"].ToString(), Convert.ToInt32(mysqlRead["rank"]), Convert.ToInt32(mysqlRead["credits"]), tClient);
}
}
}
请求的 DBManager 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ParticleFramework.Storage
{
static class DBManager
{
public static Database database;
public static Boolean Initialize(string type, string user, string pass, string host, string dbname)
{
switch (type)
{
case "sql":
database = new MySQL();
break;
default:
Log.Error("Invalid database type! (" + type + ")");
break;
}
if (database != null)
{
return database.connect(user, pass, dbname, host);
}
else
{
return false;
}
}
}
}
MySQL 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
namespace ParticleFramework.Storage
{
class MySQL : Database
{
private MySqlConnection connection;
public Boolean connect(string username, string password, string database, string host)
{
try
{
connection = new MySqlConnection(buildConnectionString(username, password, database, host));
Console.WriteLine("Database connected. Running test query...");
getString("SHOW TABLES FROM `" + database + "`");
Log.Info("Test query succeeded. Database initialized.");
closeClient();
return true;
}
catch (Exception e)
{
Log.Error("MySQL Connect: " + e.Message);
return false;
}
}
public string getString(string query)
{
try
{
string resultStr = getCommand(query).ExecuteScalar().ToString();
closeClient();
return resultStr;
}
catch (Exception e)
{
Log.Error("MySQL getString: " + e.Message);
return "";
}
}
public MySqlCommand getCommand(string query)
{
try
{
if (connection.State != System.Data.ConnectionState.Closed)
{
connection.Close();
}
MySqlCommand command = newCommand();
command.CommandText = query;
connection.Open();
return command;
}
catch (Exception e)
{
Log.Error("MySQL getCommand: " + e.Message);
return null;
}
}
public void noCommand(string query)
{
try
{
if (connection.State != System.Data.ConnectionState.Closed)
{
connection.Close();
}
MySqlCommand command = newCommand();
command.CommandText = query;
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
catch (Exception e)
{
Log.Error("MySQL noCommand: " + e.Message);
}
}
public void closeClient()
{
try
{
if (connection.State == System.Data.ConnectionState.Open)
{
connection.Close();
}
}
catch (Exception e)
{
Log.Error("MySQL closeClient: " + e.Message);
}
}
public MySqlCommand newCommand()
{
try
{
return connection.CreateCommand();
}
catch (Exception e)
{
Log.Error("MySQL newCommand: " + e.Message);
return null;
}
}
public string buildConnectionString(string username, string password, string database, string host)
{
return "Database=" + database + ";Data Source=" + host + ";User Id=" + username + ";Password=" + password;
}
}
}
数据库类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
namespace ParticleFramework.Storage
{
interface Database
{
Boolean connect(string username, string password, string database, string host);
MySqlCommand newCommand();
MySqlCommand getCommand(string query);
string buildConnectionString(string username, string password, string database, string host);
string getString(string query);
void noCommand(string query);
void closeClient();
}
}
SSO 字符串更改后的日志信息
>[1/1/0001 00:00:00] 127.0.0.1connected. Full 127.0.0.1:56765
>[1/1/0001 00:00:00] Got LO null from client 0
>[1/1/0001 00:00:00] Client 0 logging in with SSO: null
>[ERROR]Packet handler: MySql.Data.MySqlClient.MySqlException (0x80004005): Invalid attempt to access a field before calling Read()
> at MySql.Data.MySqlClient.ResultSet.get_Item(Int32 index)
> at MySql.Data.MySqlClient.MySqlDataReader.GetFieldValue(Int32 index, Boolean checkNull)
> at MySql.Data.MySqlClient.MySqlDataReader.GetValue(Int32 i)
> at MySql.Data.MySqlClient.MySqlDataReader.get_Item(Int32 i)
> at MySql.Data.MySqlClient.MySqlDataReader.get_Item(String name)
> at ArchiCruise.Users.Handler.newObject(String ssoTicket, TcpClient tClient) in C:\Users\Daniel\Desktop\AC\Particle Server\Particle Server\ArchiCruise\Users\Handler.cs:line 188
> at ArchiCruise.Users.Handler.login(String ssoTicket, TcpClient client) in C:\Users\Daniel\Desktop\AC\Particle Server\Particle Server\ArchiCruise\Users\Handler.cs:line 31
> at ArchiCruise.ArchiCruisePackets.handle(String packet, TcpClient client) in C:\Users\Daniel\Desktop\AC\Particle Server\Particle Server\ArchiCruise\ArchiCruisePackets.cs:line 23
>[1/1/0001 00:00:00] Client0 disconnected and removed.
Tcpclient 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ParticleFramework.Communication
{
class TcpClient
{
#region Required Variables
public Socket socket;
public int index;
private byte[] dataBuffer = new byte[0x400];
private AsyncCallback ReceiveCallback;
private AsyncCallback SendCallback;
#endregion
#region ArchiCruise Vars
public ArchiCruise.Users.UserObject userObject;
public string ip;
#endregion
public TcpClient(Socket sock, int num)
{
index = num;
socket = sock;
ip = socket.RemoteEndPoint.ToString().Split(new char[] { ':' })[0];
ReceiveCallback = new AsyncCallback(this.ReceivedData);
SendCallback = new AsyncCallback(this.sentData);
this.WaitForData();
}
public void Disconnect()
{
if (socket.Connected)
{
socket.Close();
if (userObject != null) userObject.remove();
Particle.Server.removeClient(this);
Log.Info("Client" + this.index + " disconnected and removed.");
Console.WriteLine("Client" + this.index + " disconnected.");
}
}
private void ReceivedData(IAsyncResult iAr)
{
try
{
int count = 0;
try
{
count = socket.EndReceive(iAr);
}
catch
{
Disconnect();
}
StringBuilder builder = new StringBuilder();
builder.Append(System.Text.Encoding.Default.GetString(this.dataBuffer, 0, count));
string str = System.Text.Encoding.Default.GetString(this.dataBuffer, 0, count);
if (str.Contains("<policy-file-requet/>"))
{
Log.Info("Sending policy file to client" + this.index);
rawSend("<?xml version\"1.0\"?><cross-domain-policy><allow-access-from-domain=\"*\" to-ports=\"*\" /><cross-domain-policy>" + Convert.ToChar(0));
}
else if (!(str.ToString() == ""))
{
string packet = str.Substring(0, str.Length - 1);
//packet = ArchiCruise.Security.Encryption.decrypt(packet);
Log.Info("Got " + str + " from client " + this.index);
Particle.packetClass.handle(packet, this);
}
else
{
Disconnect();
}
}
catch (Exception exception)
{
Log.Info("Data recieve error: " + exception.ToString() + " " + exception.Source);
Disconnect();
}
finally
{
this.WaitForData();
}
}
private void WaitForData()
{
try
{
socket.BeginReceive(this.dataBuffer, 0, this.dataBuffer.Length, SocketFlags.None, this.ReceiveCallback, socket);
}
catch
{
Disconnect();
}
}
public void sendData(string Data)
{
Data += (char)1;
rawSend(Data);
}
internal void rawSend(string Data)
{
try
{
Data += "\0";
byte[] bytes = System.Text.Encoding.Default.GetBytes(Data);
socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(this.sentData), null);
Log.Info("Sent " + Data + " to client " + this.index);
}
catch
{
Disconnect();
}
}
private void sentData(IAsyncResult iAr)
{
try
{
socket.EndSend(iAr);
}
catch
{
Disconnect();
}
}
}
}
最佳答案
我建议你使用mysql ORM .您的代码确实很容易出错,并且非常容易受到 sql 注入(inject)攻击。
但是,从您的错误日志中您可以看到您没有检查 sql 查询是否正确执行以及其中是否包含值。您可以使用 if 检查轻松完成此操作,如下所示:
public static UserObject newObject(string ssoTicket, TcpClient tClient)
{
string sqlQuery = "SELECT * FROM `users` WHERE `sso_ticket` = '" + ssoTicket + "' LIMIT 1";
MySqlDataReader mysqlRead = DBManager.database.getCommand( sqlQuery ).ExecuteReader();
if (mysqlRead.Read()) // read the query and check if we got any data
{
return new UserObject(mysqlRead["name"].ToString(), Convert.ToInt32(mysqlRead["rank"]), Convert.ToInt32(mysqlRead["credits"]), tClient);
}
else
{
Log.Error("sqlQuery failed : " + sqlQuery );
return null; //you should check the returned value if its null or not to prevent further problems.
}
}
使用此代码,您可以检查您的查询是否有误。我建议你一步一步调试,看看变量是否有正确的值。检查Debugging in Visual Studio从 Microsoft 获取有关调试的更多信息。
关于c# - 服务器不从数据库中获取信息并将其传递给客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35036557/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些