⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x6787.htm

📁 Its a xmpp protocol book
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML
><HEAD
><TITLE
>User Registration Script</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="HOME"
TITLE="Programming Jabber"
HREF="book1.htm"><LINK
REL="UP"
TITLE="User Registration and Authorization"
HREF="c6313.htm"><LINK
REL="PREVIOUS"
TITLE="User Authentication"
HREF="x6569.htm"><LINK
REL="NEXT"
TITLE="Messages, Presence, and Presence Subscription"
HREF="c6941.htm"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming Jabber</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x6569.htm"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 6. User Registration and Authorization</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c6941.htm"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="JABTDG-CH-6-SECT-5.4"
>User Registration Script</A
></H1
><P
>Currently, the Jabber technology has no concept of 'anonymous' users - users
that can connect to the server with no previous registration requirement. 
Until such time as this is possible, we will have to make do with creating
specific users for specific scenarios. </P
><P
>To this end, it would be useful to be able to run a quick script to register a
new user, rather than grab an existing client, start it up, and go through the
process of registering a new user with the Jabber server, with whatever window
navigation and mouse-clicking that might entail. All the script must do is 
interact with the Jabber server in the context of the
<TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace, specifically pre-session.
It must be able to make a registration <I
CLASS="EMPHASIS"
>enquiry</I
> by sending
an IQ get and returning the fields listed in the result, and to make a
registration <I
CLASS="EMPHASIS"
>attempt</I
>, when supplied with values for
the registration fields. </P
><P
>We should be able to invoke our script, 
<B
CLASS="COMMAND"
>reguser</B
>, in one of two ways. The first, specifying
merely a hostname (and optional port, which will default to 5222 if not
specified), implies a registration <I
CLASS="EMPHASIS"
>enquiry</I
> - where
we wish to make an enquiry of the Jabber server as to (a) whether 
registration is possible and (b) if so, what fields are 'required'.
The second way, specifying not only the host and optional port, but also
a list of fieldname and value pairs to send in a user registration
<I
CLASS="EMPHASIS"
>attempt</I
>. <A
HREF="x6787.htm#JABTDG-CH-6-FIG-3"
>Figure 6-3</A
> shows
both these ways in action.</P
><DIV
CLASS="FIGURE"
><A
NAME="JABTDG-CH-6-FIG-3"
></A
><P
><B
>Figure 6-3. Uses of the <B
CLASS="COMMAND"
>reguser</B
> script</B
></P
><PRE
CLASS="SCREEN"
>$ <TT
CLASS="USERINPUT"
><B
>./reguser yak:5222</B
></TT
>
[Enquiry] Fields: username password email name </PRE
><PRE
CLASS="SCREEN"
>$ <TT
CLASS="USERINPUT"
><B
>./reguser yak username=joseph password=spinach 'name=Joseph Adams' email=joseph@yak</B
></TT
>
[Attempt] (joseph) Successful registration</PRE
><PRE
CLASS="SCREEN"
>$ <TT
CLASS="USERINPUT"
><B
>./reguser yak username=dj password=secret 'name=DJ Adams' email=dj@yak</B
></TT
>
[Attempt] (dj) Error: 409 (Username Not Available)</PRE
></DIV
><P
>As it's our first substantial script, let's take it step by step. It's written
in Perl.</P
><P
><PRE
CLASS="SCREEN"
>#!/usr/bin/perl

use strict;
use Net::Jabber 1.0022 qw(Client);

use constant NS_REGISTER =&#62; 'jabber:iq:register';

unless (@ARGV) {
  print usage();
  exit;
}</PRE
></P
><P
>We start out with some basic start-of-script housekeeping - 
delaring our usage of the Net::Jabber module, setting a constant for
the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace, and handling the
case of being 'wrongly' invoked by giving some help text from the
<TT
CLASS="LITERAL"
>usage()</TT
> subroutine. The specification of 
"<TT
CLASS="LITERAL"
>Client</TT
>" in the </P
><P
><PRE
CLASS="SCREEN"
>use Net::Jabber 1.0022 qw(Client);</PRE
></P
><P
>means that the connection is going to be client-based; in other words,
the namespace that will be used to qualify the XML stream header that
Net::Jabber will produce is <TT
CLASS="LITERAL"
>jabber:client</TT
>. </P
><P
>The Net::Jabber module has changed as it has matured over the recent 
versions (1.0020, 1.0021 and 1.0022) and these changes do sometimes
affect how the scripts that use Net::Jabber should be written. So we
explicitly specify in the <TT
CLASS="LITERAL"
>use</TT
> statement which version
of Net::Jabber we require, to avoid confusion.</P
><P
><PRE
CLASS="SCREEN"
>my ($host, $port) = split(":", shift @ARGV);
$port ||= 5222;

my $c = Net::Jabber::Client-&#62;new();

defined($c-&#62;Connect(
            hostname =&#62; $host,
            port     =&#62; $port,
)) or die "Cannot reach Jabber server at $host:$port\n";

my ($iq, $query, $result);</PRE
></P
><P
>We parse the hostname and port, defaulting the latter to 5222 if it wasn't
specified. Then we create a new instance of the Net::Jabber::Client object.
The Net::Jabber family of modules presents its collective functions in an
object-oriented way. The scalar <TT
CLASS="LITERAL"
>$c</TT
> represents the 
'client' mechanism with which we connect to the Jabber server. </P
><P
>With the <TT
CLASS="LITERAL"
>Connect()</TT
> method, we make a connection to the
Jabber server; the namespace of the XML stream for this connection, 
sent to the Jabber server in the stream header, is 
<TT
CLASS="LITERAL"
>jabber:client</TT
>. </P
><P
><PRE
CLASS="SCREEN"
># Registration attempt or enquiry?

if (scalar @ARGV) {

  # Attempt:
  # Send &#60;iq type='set'&#62;
  #        &#60;query xmlns='jabber:iq:register'&#62;
  #          &#60;username&#62;...&#60;/username&#62;
  #          &#60;password&#62;...&#60;/password&#62;
  #          ...
  #        &#60;/query&#62;
  #      &#60;/iq&#62;

  print "[Attempt] ";

  $iq = Net::Jabber::IQ-&#62;new();
  $iq-&#62;SetType('set');
  $query = $iq-&#62;NewQuery(NS_REGISTER);</PRE
></P
><P
>We work out what we have to do by looking to see if any extra parameters
beyond the hostname and port were specified. If there were, we need to build
an IQ set in the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace to make
a registration attempt. </P
><P
>The Net::Jabber::IQ module represents the IQ model and provides methods
to manage IQ packets. With the <TT
CLASS="LITERAL"
>new()</TT
> constructor we
create a new, empty IQ packet in <TT
CLASS="LITERAL"
>$iq</TT
>, and set its 
<TT
CLASS="LITERAL"
>type</TT
> attribute to 'set'. </P
><P
>As we know, the <TT
CLASS="LITERAL"
>&#60;query/&#62;</TT
> part
of an IQ packet is contained <I
CLASS="EMPHASIS"
>within</I
> the 
<TT
CLASS="LITERAL"
>&#60;iq/&#62;</TT
> tag. The <TT
CLASS="LITERAL"
>NewQuery()</TT
>
method, called on an IQ packet, creates a <TT
CLASS="LITERAL"
>&#60;query/&#62;</TT
>
tag as a child of that IQ packet, and delivers us a handle on that
<TT
CLASS="LITERAL"
>&#60;query/&#62;</TT
> tag - which we store in 
<TT
CLASS="LITERAL"
>$query</TT
> - so that we can manipulate it independently
of the IQ packet that wraps around it. The <TT
CLASS="LITERAL"
>jabber:iq:register</TT
>
namespace value is passed as a parameter to the <TT
CLASS="LITERAL"
>NewQuery()</TT
>
call to set the correct <TT
CLASS="LITERAL"
>xmlns</TT
> namespace attribute.</P
><P
><A
HREF="x6787.htm#JABTDG-CH-6-FIG-4"
>Figure 6-4</A
> shows what the packet looks like
at this stage, and how the scalar object references <TT
CLASS="LITERAL"
>$iq</TT
>
and <TT
CLASS="LITERAL"
>$query</TT
> relate to it.</P
><DIV
CLASS="FIGURE"
><A
NAME="JABTDG-CH-6-FIG-4"
></A
><P
><B
>Figure 6-4. An IQ packet under construction by Net::Jabber::IQ</B
></P
><PRE
CLASS="SCREEN"
>&#13;  $iq -------+                         +----- $query
             |                         |
             v                         |
            &#60;iq type='set'&#62;            v
              &#60;query xmlns='jabber:iq:register'/&#62;
            &#60;/iq&#62;</PRE
></DIV
><P
>In our <TT
CLASS="LITERAL"
>foreach</TT
> loop we run through the list of 
parameters, in the form <I
CLASS="EMPHASIS"
>fieldname=value</I
>, and 
call a <TT
CLASS="LITERAL"
>Set</TT
> method on the <TT
CLASS="LITERAL"
>$query</TT
>
object (the <TT
CLASS="LITERAL"
>&#60;query/&#62;</TT
> packet) to 
add child tags:</P
><P
><PRE
CLASS="SCREEN"
>  foreach my $arg (@ARGV) {
    my ($field, $value) = split('=', $arg);
    print "($value) " if $field eq 'username';
    eval '$query-&#62;Set'.ucfirst($field).'($value)';
  }

  $result = $c-&#62;SendAndReceiveWithID($iq);</PRE
></P
><P
>Net::Jabber::Query provides a number of <TT
CLASS="LITERAL"
>SetXXXX</TT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -